#author("2019-02-01T04:07:02+00:00","","") [[AWSメモ]] > * AWS Iot にPublishデータをDBに登録する [#cea88751] #setlinebreak(on); #contents -- 関連 --- [[AWS IotでPub/Subしてみる]] https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-iot-topicrule.html https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-iot-topicrule-topicrulepayload.html https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-iot-topicrule-action.html https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/cfn-using-cli.html ** 概要 [#v046ab75] #html(<div style="padding-left: 10px;">) #TODO #html(</div>) ** DB 及び Iotルールアクションの作成 [#s30900c6] #html(<div style="padding-left: 10px;">) ここではスタックとして一括で作成する。 template.yml #mycode2(){{ AWSTemplateFormatVersion: "2010-09-09" Description: "Iot Rule action sample" Resources: # テーブル SampleIotDataTable: Type: AWS::DynamoDB::Table Properties: TableName: SampleIotData AttributeDefinitions: - AttributeName: topic AttributeType: S - AttributeName: skey AttributeType: S KeySchema: - AttributeName: topic KeyType: HASH - AttributeName: skey KeyType: RANGE ProvisionedThroughput: ReadCapacityUnits: 1 WriteCapacityUnits: 1 # テーブルに登録する為のIAMロール SampleIotDataTablePutItemRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Principal: Service: - "iot.amazonaws.com" Action: - "sts:AssumeRole" Policies: - PolicyName: "SampleIotDataTablePutItemPolicy" PolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Action: "dynamoDB:PutItem" Resource: !GetAtt SampleIotDataTable.Arn # Iotトピックルール SampleIotRuleAction: Type: AWS::IoT::TopicRule Properties: RuleName: "ToDynamoDB" TopicRulePayload: Actions: - DynamoDBv2: RoleArn: !GetAtt SampleIotDataTablePutItemRole.Arn PutItem: TableName: !Ref SampleIotDataTable AwsIotSqlVersion: "2016-03-23" Description: String RuleDisabled: false Sql: >- SELECT topic() AS topic, concat(parse_time("yyyy-MM-dd'T'HH:mm:ss.SSS'#'", timestamp()), traceid()) AS skey principal() AS principal, traceid() AS traceid, encode(*, 'base64') AS data, parse_time("yyyy-MM-dd'T'HH:mm:ss.SSSz", timestamp()) AS ts FROM 'topic/#' }} AWS CLI から一括作成 #myterm2(){{ # S3バケットの作成 aws s3api create-bucket --create-bucket-configuration '{"LocationConstraint": "ap-northeast-1"}' --bucket my-cloudformation-templates-アカウントID # 検証 aws cloudformation validate-template --template-body file://template.yml # パッケージング aws cloudformation package --template-file template.yml --s3-bucket my-cloudformation-templates-アカウントID --output-template-file packaged-template.yml # デプロイ aws cloudformation deploy --template-file packaged-template.yml --stack-name SampleIotRuleAction --capabilities CAPABILITY_IAM }} #html(</div>) ** 動作確認用の処理作成 [#w5f703d6] #html(<div style="padding-left: 10px;">) test_publish.py #mycode2(){{ # coding: utf-8 import base64 import boto3 import json from datetime import datetime import time def publish(): client = boto3.client('iot-data') now = datetime.now() payload = json.dumps({ 'message': f'Hello AWS Iot! {now}' }).encode() response = client.publish( topic='topic/SampleTopic1', qos=0, payload=payload ) print('-- publish result --') print(response) def scan_table(): dynamodb = boto3.resource('dynamodb') res = dynamodb.Table('SampleIotData').scan() items = res.get('Items') if res.get('Items') else [] print('-- items --') items = [ {**x, **{'decoded_data': json.loads(base64.b64decode(x['data'].encode()).decode())}} for x in items ] print(json.dumps(items, indent=4)) def main(): publish() time.sleep(3) scan_table() if __name__ == '__main__': main() }} #html(</div>) ** 動作確認 [#jb8fd2c3] #html(<div style="padding-left: 10px;">) #myterm2(){{ python test_publish.py }} 結果 #myterm2(){{ -- publish result -- {'ResponseMetadata': {'RequestId': '9c75d82c-de11-8ee7-ed65-7930fc29c580', 'HTTPStatusCode': 200, 'HTTPHeaders': ... }, 'RetryAttempts': 0}} -- items -- [ { "ts": "2018-01-01T03:47:39.588UTC", "principal": "AIDAJHJTUCF474FK4DJSI", "topic": "topic/SampleTopic1", "traceid": "b4b3ffa7-f2f4-a38d-7e5c-30b6b79fee81", "data": "eyJtZXNzYWdlIjogIkhlbGxvIEFXUyBJb3QhIDIwMTktMDItMDEgMTI6NDc6MzkuMzI3NTQ1In0=", "skey": "2018-01-01T03:47:39.588#b4b3ffa7-f2f4-a38d-7e5c-30b6b79fee81", "decoded_data": { "message": "Hello AWS Iot! 2018-01-01 12:47:39.327545" } } ] }} #html(</div>)