Kinesis Data FirehoseからParquetファイルでS3に書き込む

# 背景・目的
Kinesis Datga Firehose（以降、KDFといいます。）から、S3にParquetを出力する機会がなかったので試してみました。
なお、思わぬところでハマったので、忘れないように合わせて載せておきます。

# まとめ
- Firehoseだけではなく、Lakeformationの設定も必要でした。


# 概要
AthenaやRedshift　Spectrumで分析しやすいようにKDFでParquetフォーマットに変換しS3に出力します。今回は、S3 Selectで確認するところまでをスコープとします。


# 実装
## KDFの設定

1. Kinesisトップ画面で配信ストリームをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/d1ee2aa1-bc6e-b187-c305-d7c3f01f1951.png)


1. KDFの画面で以下を入力すると、設定項目が変更されます。
    - SourceにDirect Put
    - DestinationにS3
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/0d82fd8e-1bfa-d5fc-5112-f009cd342a68.png)

1. ストリーム名に名前をつけます。
1. Convert record formatでEnableを選択すると、以降の入力項目が変更されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/b8028d3b-3ae2-0967-7ac2-32b58c895810.png)

1. 変換のために以下を設定します。
    - Output formatにカラムナータイプのParquetとORCの2つが選択できますが、今回はParquetを選択します。
    - Glueリージョン
    - Glueデータベースとテーブル
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/5873c45d-0b72-d157-9d4c-699237fe0ecc.png)


1. 以下を入力しデータをフィードするS3の設定を行います。
    - S3 bucketにフィードするバケット
    - Dynamid partitionsはDisable
    - S3 bucket prefixとS3 bucket error prefixは今回は未入力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/c6623402-d863-3f88-39b1-d58b5df64d31.png)


1. 最後にCreate Delivery Streamをクリックします。（IAMロールは同時に作成されます。）
    - エラーになりました。Access DeniedExceptiongaでました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/dc473b37-6251-e22c-8432-0f8c260740b5.png)


1. IAMポリシーを修正
    - どうやらLakeFormationの権限が不足していそうです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/f4e3592c-743b-946d-b519-5c68e6cb65ae.png)

1. IAMポリシーにLakeFormationを追加
    - 一旦、LakeFormationのフルアクセス権限をポリシーに追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/72edc608-1ca5-8b3c-f1c8-7870f7183281.png)- 

1. LakeFormationのナビゲーションペインでData Lake permissionsをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/5ccf9072-68e6-9d88-4d44-b2f3f9c5d087.png)

1. permissionsでGrantをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/ef58dc00-e7d2-7bbc-043f-e8ef742598c7.png)


1. principalsでKDFで作成したIAMロールを指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/a005a2cf-4883-298f-9501-75ba76a31e5f.png)

1. LF-Tags or catalog resourcesで、「Named data catalog resources」を選択し、Databasesに該当するデータベース、Tablesは「all tables」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/81a3c71c-4481-a366-7828-1b13d7501a7c.png)

1. 以下を全て選択して、Grantをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/2689e187-bd1f-5fd4-c5be-640c5518e683.png)


1. IAMロールでフィルターをかけると対象のリソースの権限が見えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/f4940059-b978-7839-c734-8020074f03ab.png)


1. 上記の設定後、KDFで再び、「Create Delivery Stream」をクリックすると作成できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/6bb12aab-dd84-4c59-5e11-9b071c3b5613.png)


### 疎通確認
1. KDFの「Test with demo data」を実行します。 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/89618936-5176-a1dc-15b1-6e4ce641189e.png)

1. S３を確認
フィードされました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/c1760147-916a-7410-66b6-64360b1ead2a.png)

1. S3　SELECTで確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/f2bcacc0-be34-6295-fb6d-54425c994475.png)

1. 見えました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/925eb518-2e19-7bf0-3ffc-ed32e0059db2.png)
 

# 考察
今回は、KDFからS3に出力するフォーマットをParquetにしてみました。簡単にできると思いきや、デフォルトで作成される権限だけではなくLakeFormationの設定が必要でした。
少しはまりましたが、これでAthenaやRedshift　Spectrumでそのまま参照できそうです。
なお、以下については、別途整理しようと思います。
- Parquetファイルの構造
- LakeFormation

# 参考
https://aws.amazon.com/jp/premiumsupport/knowledge-center/glue-insufficient-lakeformation-permissions/