[terraform] RDSイベントをEventBridgeでNew Relicに送信する
🌱 はじめに
この記事では、Terraform で
EventBridge → New Relic のイベント連携を自動構築する手順をまとめました。
構成のベースは、サーバーワークス様のブログ記事
👉 Amazon RDSイベントをEventBridge経由でNew Relicに送信する方法 を参考にしています🙇♀️

🧩 全体構成
EventBridge の API Destination 機能を使うと、
AWSから外部サービス(今回は New Relic)へ直接HTTPSリクエストを送信できます。
構成の流れは次のとおりです。
- EventBridge Connection を作成し、New RelicへのAPIキーを登録
- API Destination を設定して送信先エンドポイントを定義
- IAMロールとポリシー を作成(EventBridgeが呼び出せるようにする)
- RDSイベントルール を作成し、トリガーを定義
- Event Target でNew Relic APIへ送信
⚙️ 事前準備:変数定義
本記事で利用している主要な変数は以下の通りです。
variable "sysname" {
description = "システム名"
type = string
}
variable "env" {
description = "環境名"
type = string
}
variable "newrelic_license_key" {
description = "New Relic INGEST-LICENSE APIキー"
type = string
sensitive = true
}
variable "rds_event_types" {
description = "RDS Event Types"
type = list(string)
default = null
}
💡ポイント
-
newrelic_license_keyには、New Relic のAPIキーのKey type:「INGEST - LICENSE」を指定します。 -
rds_event_typesには、対象とするRDSイベントカテゴリを配列で指定しています。
例:
rds_event_types = ["RDS DB Instance Event", "RDS DB Cluster Event"]
RDSが発行するイベントカテゴリを基に設定する必要があります。何も指定しない場合には、全てのRDSイベントが通知されます。
参考🔗:Amazon RDS イベントカテゴリとイベントメッセージ
1️⃣ EventBridge Connectionの作成
まず、New Relicへの接続を定義します。
resource "aws_cloudwatch_event_connection" "newrelic" {
name = "${var.sysname}-${var.env}-newrelic-connection"
description = "Connection to New Relic for events"
authorization_type = "API_KEY"
auth_parameters {
api_key {
key = "X-License-Key"
value = var.newrelic_license_key
}
}
}
EventBridgeのConnectionを作成すると、var.newrelic_license_keyで渡されたNew RelicのAPIキーの情報が/aws/events!connection/<connection名> という名前でSecrets Managerに自動的に保存されます。
2️⃣ API Destinationの作成
New Relicのログやイベント受信APIを呼び出すための宛先を定義します。
resource "aws_cloudwatch_event_api_destination" "newrelic" {
name = "${var.sysname}-${var.env}-newrelic-api-destination"
description = "API destination for New Relic events"
http_method = "POST"
invocation_endpoint = "https://log-api.newrelic.com/log/v1"
invocation_rate_limit_per_second = 10
connection_arn = aws_cloudwatch_event_connection.newrelic.arn
}
これでEventBridgeがNew RelicのログインジェストAPIにアクセスできるようになります。
3️⃣ IAMロールとポリシーの設定
EventBridgeがAPI Destinationを呼び出せるようにIAMロールを作成します。
resource "aws_iam_role" "eventbridge" {
name = "${var.sysname}-${var.env}-newrelic-eventbridge-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = {
Service = "events.amazonaws.com"
}
}
]
})
}
次に、Secrets ManagerおよびAPI Destinationを呼び出す権限を付与します。
data "aws_caller_identity" "current" {}
resource "aws_iam_role_policy" "eventbridge" {
name = "${var.sysname}-${var.env}-newrelic-eventbridge-policy"
role = aws_iam_role.eventbridge.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = ["events:InvokeApiDestination"]
Resource = aws_cloudwatch_event_api_destination.newrelic.arn
},
{
Effect = "Allow"
Action = ["secretsmanager:GetSecretValue"]
Resource = "arn:aws:secretsmanager:*:${data.aws_caller_identity.current.account_id}:secret:events!connection/${aws_cloudwatch_event_connection.newrelic.name}/*"
}
]
})
}
secretsmanager:GetSecretValueで
EventBridgeがSecrets Managerに保存されたNew RelicのAPIキーの情報を取得するために必要な権限を付与しています。
4️⃣ RDSイベントルールの定義
どのイベントをトリガーとして送信するかを指定します。
resource "aws_cloudwatch_event_rule" "rds" {
name = "${var.sysname}-${var.env}-newrelic-rds-rule"
description = "Capture RDS events and send to New Relic"
event_pattern = jsonencode({
source = ["aws.rds"]
detail-type = var.rds_event_types
})
}
本記事では監視対象のRDSイベントタイプを配列でパラメータで渡しています。
5️⃣ Event Targetの設定
最後に、キャッチしたイベントをNew Relic API DestinationへPOSTするターゲットを設定します。
resource "aws_cloudwatch_event_target" "newrelic" {
rule = aws_cloudwatch_event_rule.rds.name
arn = aws_cloudwatch_event_api_destination.newrelic.arn
role_arn = aws_iam_role.eventbridge.arn
http_target {
header_parameters = {
"Content-Type" = "application/json"
}
}
depends_on = [aws_iam_role_policy.eventbridge]
}
これで、RDSイベント発生時にEventBridgeが自動でNew Relic APIにリクエストを送信します。
送信されたイベントは、New Relicのログ画面やイベントビューアで確認できます 📊
🔔 おまけ:New Relic→SlackへRDSイベントを通知する
New Relic側でNRQLアラートを設定して、RDSイベントをSlackへ通知するようにしました。
以下はアラートポリシーのTerraformコードの例です。
NRQLで detail.EventID に "rds" を含むイベントを検知したらwarning通知を出すようにしています。
resource "newrelic_nrql_alert_condition" "db_event" {
account_id = <NEWRELIC_ACCOUNT_ID>
policy_id = <NEWRELIC_POLICY_ID>
type = "static"
name = "DB EVENT"
description = trimspace(<<-EOT
target is : {{tags.detail.SourceIdentifier}}
message is : {{tags.detail.Message}}
EOT
)
enabled = true
violation_time_limit_seconds = 259200
nrql {
query = "SELECT COUNT(*) FROM Log WHERE detail.EventID LIKE %rds% FACET detail.SourceIdentifier, detail.Message"
}
warning {
operator = "above_or_equals"
threshold = 1
threshold_duration = 300
threshold_occurrences = "at_least_once"
}
fill_option = "none"
aggregation_window = 60
aggregation_method = "event_timer"
aggregation_timer = 60
title_template = "{{conditionName}}: {{tags.detail.Message}} - {{tags.detail.SourceIdentifier}}"
}
💡ポイント
-
detail.SourceIdentifierやdetail.Messageは、EventBridgeから転送されたRDSイベントのフィールドです。 -
title_templateを設定することで、通知メッセージにイベント内容を直接含められます。
🚀 さいごに
上記の構成を1ファイルにまとめたTerraformコード例をまとめて終わりたいと思います。
この記事がどなたかの参考になれば幸いです。
えみり〜でした|ωΦ)ฅ
terraform コード全文
variable "sysname" {
description = "システム名"
type = string
}
variable "env" {
description = "環境名"
type = string
}
variable "newrelic_license_key" {
description = "New Relic INGEST-LICENSE APIキー"
type = string
sensitive = true
}
variable "rds_event_types" {
description = "RDS Event Types"
type = list(string)
default = ["RDS DB Instance Event", "RDS DB Cluster Event"]
}
data "aws_caller_identity" "current" {}
resource "aws_cloudwatch_event_connection" "newrelic" {
name = "${var.sysname}-${var.env}-newrelic-connection"
description = "Connection to New Relic for events"
authorization_type = "API_KEY"
auth_parameters {
api_key {
key = "X-License-Key"
value = var.newrelic_license_key
}
}
}
resource "aws_cloudwatch_event_api_destination" "newrelic" {
name = "${var.sysname}-${var.env}-newrelic-api-destination"
description = "API destination for New Relic events"
http_method = "POST"
invocation_endpoint = "https://log-api.newrelic.com/log/v1"
invocation_rate_limit_per_second = 10
connection_arn = aws_cloudwatch_event_connection.newrelic.arn
}
resource "aws_iam_role" "eventbridge" {
name = "${var.sysname}-${var.env}-newrelic-eventbridge-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = {
Service = "events.amazonaws.com"
}
}
]
})
}
resource "aws_iam_role_policy" "eventbridge" {
name = "${var.sysname}-${var.env}-newrelic-eventbridge-policy"
role = aws_iam_role.eventbridge.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = ["events:InvokeApiDestination"]
Resource = aws_cloudwatch_event_api_destination.newrelic.arn
},
{
Effect = "Allow"
Action = ["secretsmanager:GetSecretValue"]
Resource = "arn:aws:secretsmanager:*:${data.aws_caller_identity.current.account_id}:secret:events!connection/${aws_cloudwatch_event_connection.newrelic.name}/*"
}
]
})
}
resource "aws_cloudwatch_event_rule" "rds" {
name = "${var.sysname}-${var.env}-newrelic-rds-rule"
description = "Capture RDS events and send to New Relic"
event_pattern = jsonencode({
source = ["aws.rds"]
detail-type = var.rds_event_types
})
}
resource "aws_cloudwatch_event_target" "newrelic" {
rule = aws_cloudwatch_event_rule.rds.name
arn = aws_cloudwatch_event_api_destination.newrelic.arn
role_arn = aws_iam_role.eventbridge.arn
http_target {
header_parameters = {
"Content-Type" = "application/json"
}
}
depends_on = [aws_iam_role_policy.eventbridge]
}
Discussion