Kinesis Data Firehoseのエラーロギングをマネコン以外で設定する際の注意点

Kinesis Data Firehoseはデータ配信処理やデータ変換用のLambda関数の処理失敗時に、そのエラーログをCloudWatchLogsに出力するように設定することが出来ます。その設定方法や挙動を調査する過程で把握出来た注意事項を2つ、備忘録的に記載します。
※以降、「Kinesis Data Firehose」だと長いので、「Firehose」と省略します。

**※2020年12月5日時点でのFirehoseサービスの仕様をベースにしています。**

# 注意事項①
Firehoseのエラーロギング設定はマネコンからもCLI(AWS CLIやCloduFOrmation、Terraform)からも行うことは出来ますが、両者で設定の挙動に微妙な違いがります。

- マネコンから設定

>If you enable Kinesis Data Firehose error logging in the Kinesis Data Firehose console, a log group and corresponding log streams are created for the delivery stream on your behalf. The format of the log group name is /aws/kinesisfirehose/delivery-stream-name, where delivery-stream-name is the name of the corresponding delivery stream. The log stream name is S3Delivery, RedshiftDelivery, or ElasticsearchDelivery, depending on the delivery destination.

>[公式ドキュメント](https://docs.aws.amazon.com/firehose/latest/dev/monitoring-with-cloudwatch-logs.html)より

**マネコンからの場合、設定されるロググループ名は一律/aws/kinesisfirehose/{配信ストリーム名}となり、ログストリーム名は送信先によって一律S3Delivery、 RedshiftDelivery、またはElasticsearchDeliveryとなります。また、自動でロググループとログストリームが作成されます。**

- マネコン以外(CLI)から設定

>You can enable Kinesis Data Firehose error logging through the AWS CLI, the API, or AWS CloudFormation using the CloudWatchLoggingOptions configuration. To do so, create a log group and a log stream in advance. 

>[公式ドキュメント](https://docs.aws.amazon.com/firehose/latest/dev/monitoring-with-cloudwatch-logs.html)より

**マネコン以外からの場合、設定されるロググループ名およびログストリーム名はユーザが指定することが出来ます。ただし、ロググループおよびログストリームは自動作成されないので、ユーザが別途作成しておく必要があります。**

**なお下記例の様に、（少なくともTerraformは）指定先のロググループとログストリームが存在していなくても、エラーログ出力先として設定に成功してしまうので要注意です。エラーが実際に発生したら作成される、といったことも無いので要注意です。**


```tf:エラーログ出力先をユーザが指定する場合の例
provider "aws" {
  region = "ap-northeast-1"
}

resource "aws_kinesis_firehose_delivery_stream" "extended_s3_stream" {
  name        = "firehose-with-custom-error-logging"
  destination = "extended_s3"

  extended_s3_configuration {
    cloudwatch_logging_options {
      enabled         = true
      log_group_name  = "not-exist-group"
      log_stream_name = "not-exist-stream"
    }
    buffer_size     = 1
    buffer_interval = 60
    role_arn        = aws_iam_role.firehose_role.arn
    bucket_arn      = aws_s3_bucket.bucket.arn

  }
}

resource "aws_s3_bucket" "bucket" {
  bucket = "tf-test-bucket-20201205"
  acl    = "private"
}

resource "aws_iam_role" "firehose_role" {
  name = "firehose_test_role"

  assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Principal": {
        "Service": "firehose.amazonaws.com"
      },
      "Effect": "Allow",
      "Sid": ""
    }
  ]
}
EOF
}

```
```bash:ロググループとログストリームが存在しなくてもリソースの作成に成功
$ terraform apply -auto-approve
aws_iam_role.firehose_role: Creating...
aws_s3_bucket.bucket: Creating...
aws_iam_role.firehose_role: Creation complete after 2s [id=firehose_test_role]
aws_s3_bucket.bucket: Creation complete after 2s [id=tf-test-bucket-20201205]
aws_kinesis_firehose_delivery_stream.extended_s3_stream: Creating...
aws_kinesis_firehose_delivery_stream.extended_s3_stream: Still creating... [10s elapsed]
aws_kinesis_firehose_delivery_stream.extended_s3_stream: Still creating... [20s elapsed]
aws_kinesis_firehose_delivery_stream.extended_s3_stream: Still creating... [30s elapsed]
aws_kinesis_firehose_delivery_stream.extended_s3_stream: Still creating... [40s elapsed]
aws_kinesis_firehose_delivery_stream.extended_s3_stream: Creation complete after 46s [id=arn:aws:firehose:ap-northeast-1:XXXXXXXXXXXX:deliverystream/firehose-with-custom-error-logging]

Apply complete! Resources: 3 added, 0 changed, 0 destroyed.
```

```bash:エラーロギング設定を確認
$  aws logs describe-log-groups --log-group-name-prefix not-exist-
{
    "logGroups": []
}
$ aws firehose  describe-delivery-stream --delivery-stream-name firehose-with-custom-error-logging | jq .DeliveryStreamDescription.Destinations[0].S3DestinationDescription.CloudWatchLoggingOptions
{
  "Enabled": true,
  "LogGroupName": "not-exist-group",
  "LogStreamName": "not-exist-stream"
}
```

何らかの制約で独自のロググループやログストリームを指定したい場合はご注意ください。

# 注意事項②

前述した通り、CLI経由であればエラーログ出力先となるロググループ名とログストリーム名をユーザが指定できます。**ただし、後からマネコン上でFirehoseの設定を編集すると、（エラーロギングと無関係な変更でも）勝手にエラーログ出力先がデフォルトの設定で上書きされてしまいます。（ロググループが/aws/kinesisfirehose/{配信ストリーム名}となり、ログストリーム名が送信先によって一律S3Delivery、 RedshiftDelivery、またはElasticsearchDeliveryとなる。）**

![マネコンから設定値を編集.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/866958/7301d251-c6c7-de5a-cc99-0fa5f33c3cb5.jpeg)

```bash:エラーログと無関係な設定(例えばバッファサイズ)を変更すると、勝手にエラーログ設定まで変わる
$ aws firehose  describe-delivery-stream --delivery-stream-name firehose-with-custom-error-logging | jq .DeliveryStreamDescription.Destinations[0].S3DestinationDescription.CloudWatchLoggingOptions
{
  "Enabled": true,
  "LogGroupName": "/aws/kinesisfirehose/firehose-with-custom-error-logging",
  "LogStreamName": "S3Delivery"
}
```

こうなってしまうと、元々設定していた出力先（今回の例であればロググループが"not-exist-group"、ログストリームが"not-exist-stream"）にログが出力されなくなります。また、上書き設定された/aws/kinesisfirehose/firehose-with-custom-error-loggingとS3Deliveryについても実リソースが作成されているわけではないので、どこにもエラーログが出力されなくなってしまいます。

Terraform（やCloudFormation）でリソースを作成したのなら、それ以降も同じ手段でリソースを管理し続けるのがIaCの鉄則だとは思いますが、何らかの事情でマネコンからしかリソースを編集出来ない場合は、この点をご留意ください。