 
        こんにちは、香田です。
今回はCloudWatch Metric Streamsを利用しNewRelicへメトリクスを送信する方法について紹介します。
NewRelicは無料で開始可能ですので、事前に下記を参考にサインアップしてみてください。
NewRelic AWSインテグレーション
NewRelicへCloudWatch メトリクス等のAWSデータを送信する方法として、下記のようにMetric streamsとAPI pollingの2つの方法でデータ送信が可能です。

API pollingの場合は、NewRelicにて定期的にAWS APIを呼び出しメトリクスとメタデータを取得します。
Metric streamsの場合、CloudWatch Metric Streamsを利用しKinesis Data Firehoseによってメトリクスが送信される為、API pollingと比較しデータ送信の速度やAPIのスロットリングが発生しないなどといったメリットがあります。
今回はMetric streamsを利用したデータ送信の方式について説明していきます。
NewRelic Metric Streamsの設定
今回、NewRelicで利用するMetric Streamsのセットアップにterraformを利用した手順を説明していきます。
セットアップの事前準備として、AWS インテグレーションモードの選択でMetric streamsを選択し、AWSアカウントの追加設定を実施しておいてください。

Terraform AWSプロバイダの設定
はじめにAWSのリソース作成用にAWSプロバイダを設定します。
provider "aws" {
  region = "ap-northeast-1"
}S3バケットの作成
送信に失敗したメトリックデータ保管用のS3バケットを作成します。
resource "random_id" "this" {
  byte_length = 8
}
resource "aws_s3_bucket" "this" {
  bucket        = "newrelic-firehose-backup-${random_id.this.hex}"
  force_destroy = true
}
resource "aws_s3_bucket_acl" "this" {
  bucket = aws_s3_bucket.this.id
  acl    = "private"
}
resource "aws_s3_bucket_versioning" "this" {
  bucket = aws_s3_bucket.this.id
  versioning_configuration {
    status = "Suspended"
  }
}
resource "aws_s3_bucket_public_access_block" "this" {
  bucket              = aws_s3_bucket.this.id
  block_public_acls   = true
  block_public_policy = true
}Kinesis Firehoseの作成
Kinesis Firehoseで利用するIAM Roleを作成します。
resource "aws_iam_role" "newrelic_firehose" {
  name = "newrelic-firehose"
  assume_role_policy = jsonencode({
    "Version" : "2012-10-17",
    "Statement" : [
      {
        "Action" : "sts:AssumeRole",
        "Principal" : {
          "Service" : "firehose.amazonaws.com"
        },
        "Effect" : "Allow"
      }
    ]
  })
}
resource "aws_iam_role_policy" "newrelic_firehose" {
  name = "newrelic-firehose"
  role = aws_iam_role.newrelic_firehose.id
  policy = jsonencode({
    "Version" : "2012-10-17",
    "Statement" : [
      {
        "Effect" : "Allow",
        "Action" : [
          "s3:AbortMultipartUpload",
          "s3:GetBucketLocation",
          "s3:GetObject",
          "s3:ListBucket",
          "s3:ListBucketMultipartUploads",
          "s3:PutObject"
        ],
        "Resource" : [
          "${aws_s3_bucket.this.arn}",
          "${aws_s3_bucket.this.arn}/*"
        ]
      }
    ]
  })
}NewRelic ライセンスキーを発行し設定します。
variable "newrelic_license_key" {
  type        = string
  default     = "<NewRelic ライセンスキー>"
  description = "newrelic license key"
}Kinesis Firehoseを作成します。
resource "aws_kinesis_firehose_delivery_stream" "this" {
  name        = "newrelic-delivery-stream"
  destination = "http_endpoint"
  http_endpoint_configuration {
    url                = "https://aws-api.newrelic.com/cloudwatch-metrics/v1"
    name               = "New Relic"
    access_key         = var.newrelic_license_key
    role_arn           = aws_iam_role.newrelic_firehose.arn
    s3_backup_mode     = "FailedDataOnly"
    retry_duration     = 60
    buffering_interval = 60
    buffering_size     = 1
    cloudwatch_logging_options {
      enabled = false
    }
    request_configuration {
      content_encoding = "GZIP"
    }
  }
  s3_configuration {
    bucket_arn         = aws_s3_bucket.this.arn
    buffer_interval    = 300
    buffer_size        = 5
    compression_format = "GZIP"
    role_arn           = aws_iam_role.newrelic_firehose.arn
    cloudwatch_logging_options {
      enabled = false
    }
  }
}Metric Streamsの作成
Metric Streamsで利用するIAM Roleを作成します。
resource "aws_iam_role" "newrelic_metric_stream" {
  name = "newrelic-metric-stream"
  assume_role_policy = jsonencode({
    "Version" : "2012-10-17",
    "Statement" : [
      {
        "Action" : "sts:AssumeRole",
        "Principal" : {
          "Service" : "streams.metrics.cloudwatch.amazonaws.com"
        },
        "Effect" : "Allow"
      }
    ]
  })
}
resource "aws_iam_role_policy" "newrelic_metric_stream" {
  name = "newrelic-metric-stream"
  role = aws_iam_role.newrelic_metric_stream.id
  policy = jsonencode({
    "Version" : "2012-10-17",
    "Statement" : [
      {
        "Effect" : "Allow",
        "Action" : [
          "firehose:PutRecord",
          "firehose:PutRecordBatch"
        ],
        "Resource" : aws_kinesis_firehose_delivery_stream.this.arn
      }
    ]
  })
}Metric Streamsを作成します。
resource "aws_cloudwatch_metric_stream" "newrelic" {
  name          = "newrelic-metric-stream"
  role_arn      = aws_iam_role.newrelic_metric_stream.arn
  firehose_arn  = aws_kinesis_firehose_delivery_stream.this.arn
  output_format = "opentelemetry0.7"
}AWSリソースの作成
terraform applyを実行しAWSリソースを作成します。
$ terraform init
$ terraform applyMetric Streamsからのデータ送信確認
各AWSリソースの作成が完了後、しばらくするとデータが送信されてきます。
Metrics Streamsからのデータ送信確認はNewRelic Query builderを利用し確認可能です。
Query builder画面より下記のクエリを実行してみてください。
SELECT * FROM Metric WHERE collector.name='cloudwatch-metric-streams' SINCE 5 minutes ago実行すると下記のようにメトリクス データが表示されるはずです。

さいごに
CloudWatch Metric Streamsを利用しNewRelicへメトリクスを送信する方法如何でしたでしょうか?
Metric streamsを利用することで、新しいAWSサービスが登場しメトリックが追加されたときも、すぐにNewRelic側で利用可能になるのでメリットは大きいのではないでしょうか。
最後までご覧いただきありがとうございます。