AWS IoT Core における Kinesis Firehose のレコード区切り設定
IoT Core のトピックルールにある Firehose アクションで区切り文字を設定し、S3 にレコードを改行区切りで格納する方法を解説します。
IoT Core のトピックルールでは、個々の Firehose レコードの間に区切り文字を挿入できます。後続のコンシューマーが、連結されたレコードではなく改行区切りの出力を必要とする場合に使用します。
構築
該当する設定は、13〜14 行目の Separator: |+ <NEW_LINE> です。
AWSTemplateFormatVersion: "2010-09-09"
Resources: TopicRule: Type: AWS::IoT::TopicRule Properties: RuleName: topic_rule_firehose_separator_test TopicRulePayload: Actions: - Firehose: DeliveryStreamName: !Ref Firehose RoleArn: !GetAtt IamTopicRule.Arn Separator: |+
AwsIotSqlVersion: 2016-03-23 RuleDisabled: false Sql: !Sub SELECT * FROM 'topic_rule_firehose_separator_test'
Firehose: Type: AWS::KinesisFirehose::DeliveryStream Properties: DeliveryStreamName: topic-rule-firehose-separator-test DeliveryStreamType: DirectPut S3DestinationConfiguration: BucketARN: !GetAtt S3.Arn BufferingHints: IntervalInSeconds: 60 SizeInMBs: 5 CompressionFormat: GZIP ErrorOutputPrefix: "error/!{firehose:error-output-type}/!{timestamp:'year='yyyy'/month='MM'/day='dd'/hour='HH}/" Prefix: "success/!{timestamp:'year='yyyy'/month='MM'/day='dd'/hour='HH}/" RoleARN: !GetAtt IamFirehose.Arn
S3: Type: AWS::S3::Bucket Properties: BucketEncryption: ServerSideEncryptionConfiguration: - ServerSideEncryptionByDefault: SSEAlgorithm: AES256 BucketName: topic-rule-firehose-separator-test PublicAccessBlockConfiguration: BlockPublicAcls: TRUE BlockPublicPolicy: TRUE IgnorePublicAcls: TRUE RestrictPublicBuckets: TRUE
IamTopicRule: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: iot.amazonaws.com Action: sts:AssumeRole Policies: - PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: firehose:PutRecord Resource: - !GetAtt Firehose.Arn PolicyName: policy RoleName: iam-topic-rule
IamFirehose: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: firehose.amazonaws.com Action: sts:AssumeRole Condition: StringEquals: sts:ExternalId: !Ref AWS::AccountId Policies: - PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - glue:GetTable - glue:GetTableVersion - glue:GetTableVersions Resource: "*" - Effect: Allow Action: - s3:AbortMultipartUpload - s3:GetBucketLocation - s3:GetObject - s3:ListBucket - s3:ListBucketMultipartUploads - s3:PutObject Resource: - !GetAtt S3.Arn - Fn::Sub: - ${arn}/* - {arn: !GetAtt S3.Arn} - Effect: Allow Action: - lambda:InvokeFunction - lambda:GetFunctionConfiguration Resource: !Sub arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:%FIREHOSE_DEFAULT_FUNCTION%:%FIREHOSE_DEFAULT_VERSION% - Effect: Allow Action: - logs:PutLogEvents Resource: - !Sub arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/kinesisfirehose/topic-rule-firehose-separator-test - Effect: Allow Action: - kinesis:DescribeStream - kinesis:GetShardIterator - kinesis:GetRecords Resource: !Sub arn:aws:kinesis:${AWS::Region}:${AWS::AccountId}:stream/%FIREHOSE_STREAM_NAME% - Effect: Allow Action: - kms:Decrypt Resource: - !Sub arn:aws:kms:${AWS::Region}:${AWS::AccountId}:key/%SSE_KEY_ID% Condition: StringEquals: kms:ViaService: kinesis.%REGION_NAME%.amazonaws.com StringLike: kms:EncryptionContext:aws:kinesis:arn: !Sub arn:aws:kinesis:%REGION_NAME%:${AWS::AccountId}:stream/%FIREHOSE_STREAM_NAME% PolicyName: policy RoleName: iam-firehoseCloudFormation スタックをデプロイします。
aws cloudformation deploy \ --template template.yaml \ --stack-name topic-rule-firehose-separator-test \ --capabilities CAPABILITY_NAMED_IAMトピックルールの設定を確認します。
aws iot get-topic-rule \ --rule-name topic_rule_firehose_separator_test出力の 12 行目に separator の設定が表示されます。
{ "ruleArn": "arn:aws:iot:<YOUR_REGION>:<YOUR_ACCOUNT_ID>:rule/topic_rule_firehose_separator_test", "rule": { "ruleName": "topic_rule_firehose_separator_test", "sql": "SELECT * FROM 'topic_rule_firehose_separator_test'", "createdAt": "2020-05-13T10:29:18+09:00", "actions": [ { "firehose": { "roleArn": "arn:aws:iam::<YOUR_ACCOUNT_ID>:role/iam-topic-rule", "deliveryStreamName": "topic-rule-firehose-separator-test", "separator": "\n" } } ], "ruleDisabled": false, "awsIotSqlVersion": "2016-03-23" }}テスト
トピック topic_rule_firehose_separator_test にテストメッセージを送信します。
aws iot-data publish \ --topic topic_rule_firehose_separator_test \ --payload '{"id": 1, "message": "Hello from AWS IoT"}' \ --cli-binary-format raw-in-base64-out
aws iot-data publish \ --topic topic_rule_firehose_separator_test \ --payload '{"id": 2, "message": "Hello from AWS IoT"}' \ --cli-binary-format raw-in-base64-out生成されたオブジェクトを S3 から取得して確認できます。
# Check an object.$ aws s3 ls topic-rule-firehose-separator-test --recursive2020-05-14 11:30:59 68 success/year=2020/month=05/day=14/hour=02/topic-rule-firehose-separator-test-1-2020-05-14-02-29-57-593d65e5-beb6-47b1-8266-83e869b0cccb.gz
# Download the object.$ aws s3 cp s3://topic-rule-firehose-separator-test/success/year=2020/month=05/day=14/hour=02/topic-rule-firehose-separator-test-1-2020-05-14-02-29-57-593d65e5-beb6-47b1-8266-83e869b0cccb.gz ./result.gz出力には、設定したセパレーターで区切られた 2 件のレコードが含まれているはずです。
# Check the JSON.$ gunzip -c result.gz > result.json$ cat result.json{"id": 1, "message": "Hello from AWS IoT"}{"id": 2, "message": "Hello from AWS IoT"}
# Delete the results.$ rm result.gz result.json$ aws s3 rm s3://topic-rule-firehose-separator-test/success/year=2020/month=05/day=14/hour=02/topic-rule-firehose-separator-test-1-2020-05-14-02-29-57-593d65e5-beb6-47b1-8266-83e869b0cccb.gz後片付け
作業が終わったらスタックを削除します。
aws cloudformation delete-stack --stack-name topic-rule-firehose-separator-testまとめ
IoT トピックルールの Firehose アクションに Separator を追加すると、2 件のテストレコードが連結されず、改行区切りの JSON として S3 オブジェクトに格納されます。
Separator: |+ は、改行として解釈される YAML のブロックスカラーです。このプロパティがない場合は、後続処理に連結されたレコードを分割するロジックが必要になります。
本番トラフィックを流す前に、aws iot get-topic-rule で設定を確認し、ダウンロードして展開したオブジェクトでも区切り文字を確認してください。区切り文字が設定されていなくてもエラーは発生せず、レコードがそのまま連結されます。
Related posts
SiteWise Edge Gateway で OPC UA データを Kinesis にストリーミングする
SiteWise Edge Gateway とカスタムの Greengrass コンポーネントを使い、OPC UA テレメトリを Kinesis Data Streams へ橋渡しします。
Kinesis Firehose の動的パーティショニングで NDJSON 処理を簡素化する
Kinesis Data Firehose の動的パーティショニングを使い、変換用の Lambda 関数を用意せずに NDJSON(改行区切り JSON)を S3 へ出力します。
AWS IoT のペイロード値で Kinesis レコードをパーティショニングする
IoT トピックのペイロードに含まれる顧客 ID を Kinesis のパーティションキーとして使い、顧客ごとのレコード順序を維持する方法を解説します。
Athena と Kinesis Data Firehose で S3 のログをクエリする
Kinesis Data Firehose でログを S3 に配信し、Athena でクエリします。カスタムプレフィックスを使ってパーティションを自動登録する方法を解説します。
Docker 環境で Greengrass コンポーネントをビルド・デプロイする
Greengrass Core Docker イメージを使い、AWS IoT Greengrass コンポーネントをローカルで開発します。
