(5)paho.mqttでセンサーデータをラズパイからAWS IoTにPublishと(6)ラズパイでイベント録画してS3にuploadで説明したPython codesをラズパイで自動起動する為の設定です。
ラズパイのコマンドラインからcrontabで環境変数と自動実行スクリプトを書込みます。.profileへは環境変数を直接書き込みます。
crontabで書込み
起動時に展開する内容をコマンドラインからcron_mod.confファイルにまとめて、crontabで書き込みます。
ラズパイからAWS IoTへのPublishで使う環境変数
モノの登録と証明書の発行で設定したモノの名前、証明書、鍵、エンドポイントを読み込んでcron_mod.confに書き出します。
モノの名前がCatBed1の場合、これらの情報はモノを登録して証明書を作成した際に/home/userに以下のようなファイル名で出力されます。
/home/user
・
・
┣ /cert
┃ ┣ CatBed1-certificate.pem.crt
┃ ┣ CatBed1-private.pem.key
┃ ┣ AmazonRootCA1.pem
┃ ┣ end_point.json
┃ ┣ create-thing.json
┃ ┣ create-keys-and-certificate.json
┃ ・
もう一つ(2)見守りProjectの設計で出力した./src/cert/iot_prov_configのパラメーターも読み込んでcron_mod.confに書き込みます。
THING_NAME=CatBed1
TOPIC_DETECT=CatBed1/count
S3BUCKET=neko-mimamori
AWS_AccountId=${your AWS account id}
SENSOR_NO=1
PREFIX_IN=Place1
TRIGGER_SELECT=1
HOST_ENDPOINT:AWS IoTのエンドポイント
echo HOST_ENDPOINT=$(jq -r '.endpointAddress' < ./end_point.json) >> cron_mod.conf
CLIENTCERT:クライアント証明書
echo CLIENTCERT=./cert/${THING_NAME}-certificate.pem.crt >> cron_mod.conf
CLIENTKEY:クライアント証明書の秘密鍵
echo CLIENTKEY=./cert/${THING_NAME}-private.pem.key >> cron_mod.conf
CACERT:クライアント証明書の作成時に署名した認証局の証明書
echo CACERT=./cert/AmazonRootCA1.pem >> cron_mod.conf
TOPIC_DETECT:mqtt topic
echo TOPIC_DETECT="${THING_NAME}/count" >> cron_mod.conf
SENSOR_NO:センサータイプ
echo SENSOR_NO=$(cat ./iot_prov_config | grep SENSOR_NO | awk -F'=' '{print $2}') >> cron_mod.conf
イベント録画してS3にuploadするのに使う環境変数
ラズパイのコマンドラインからaws configureを実行済みの環境では、.awsの下にcredentialsとconfigというdirectoryが作られていて情報が格納されています。
boto3の利用に必要なcredentialはcredentialsに、regionはconfigから読み取ります。
/home/user
・
・
┣ /.aws
┃ ┣ credentials
┃ ┣ config
┃ ・
録画のupload先S3Bucket名は./src/cert/iot_prov_configから読み取ります。
以下順番にcron_mod.confに書き出します。
ACCESS_KEY:IAM userのCredential
echo ACCESS_KEY=$(cat ../.aws/credentials | grep aws_access_key_id | awk -F'= ' '{print $2}') >> cron_mod.conf
SECRET_KEY:IAM userのCredential
echo SECRET_KEY=$(cat ../.aws/credentials | grep aws_secret_access_key | awk -F'= ' '{print $2}') >> cron_mod.conf
REGION:モノを登録したAWSのregion
echo REGION=$(cat ../.aws/config | grep region | awk -F'= ' '{print $2}') >> cron_mod.conf
S3BUCKET:イベント映像upload先のS3Bucket名
echo S3BUCKET=$(cat ./iot_prov_config | grep S3BUCKET | awk -F'=' '{print $2}') >> cron_mod.conf
PREFIX_IN:ラズパイ設置場所の番号でPlace1~Place4に固定(修正予定)
echo PREFIX_IN=$(cat ./iot_prov_config | grep PREFIX_IN | awk -F'=' '{print $2}') >> cron_mod.conf
SENSOR_NO:センサータイプ
echo SENSOR_NO=$(cat ./iot_prov_config | grep SENSOR_NO | awk -F'=' '{print $2}') >> cron_mod.conf
TRIGGER_SELECT:イベント録画のトリガータイプ
echo TRIGGER_SELECT=$(cat ./iot_prov_config | grep TRIGGER_SELECT | awk -F'=' '{print $2}') >> cron_mod.conf
自動起動設定
ラズパイ起動時にmain.pyとemr_rec.pyを自動起動させる設定をします。
echo @reboot python ~/main.py >> cron_mod.conf
echo @reboot python ~/emr_rec.py >> cron_mod.conf
もう一つ、コマンドラインから手動実行する為に環境変数のみを.profileに追記したかったので、起動時に.profileを実行させます。開発時に必要だった設定でそのまま残してあります。
echo @reboot ~/.profile >> cron_mod.conf
crontabで書込み実行
起動時に展開する内容を書き込みます。
crontab ./cron_mod.conf
.profileへの環境変数の書込み
「@ reboot」で始まる自動起動設定以外の内容をcrontab ./cron_mod.confを実行する前に.profileにも書き込みます。こちらはconf等中間ファイルを介さず直接書込みます。
echo export HOST_ENDPOINT=$(jq -r '.endpointAddress' < ./end_point.json) >> ../.profile
echo export CACERT=./cert/AmazonRootCA1.pem >> ../.profile
echo export CLIENTCERT=./cert/${THING_NAME}-certificate.pem.crt >> ../.profile
echo export CLIENTKEY=./cert/${THING_NAME}-private.pem.key >> ../.profile
echo export >> ../.profile
echo export TOPIC_DETECT=$(cat ./iot_prov_config | grep TOPIC_DETECT | awk -F'=' '{print $2}') >> ../.profile
echo export >> ../.profile
echo export ACCESS_KEY=$(cat ../.aws/credentials | grep aws_access_key_id | awk -F'= ' '{print $2}') >> ../.profile
echo export SECRET_KEY=$(cat ../.aws/credentials | grep aws_secret_access_key | awk -F'= ' '{print $2}') >> ../.profile
echo export REGION=$(cat ../.aws/config | grep region | awk -F'= ' '{print $2}') >> ../.profile
echo export SENSOR_NO=$(cat ./iot_prov_config | grep SENSOR_NO | awk -F'=' '{print $2}') >> ../.profile
echo export S3BUCKET=$(cat ./iot_prov_config | grep S3BUCKET | awk -F'=' '{print $2}') >> ../.profile
echo export PREFIX_IN=$(cat ./iot_prov_config | grep PREFIX_IN | awk -F'=' '{print $2}') >> ../.profile
echo export TRIGGER_SELECT=$(cat ./iot_prov_config | grep TRIGGER_SELECT | awk -F'=' '{print $2}') >> ../.profile
モノの登録から自動起動登録まで一括実行
以上説明した手順は(4)モノの登録と証明書の発行で説明したcliコマンドと併せてシェルスクリプト化して/home/user/Monitoring-system-with-Raspberry-Pi-and-AWS/cert/iot_prov.shにまとめてあります。
連続投稿の最後に予定している「(10) 以上の内容を一部シェルスクリプトにまとめてcliで連続実装」の中で実行します。
#!/bin/bash
#/home/pi/ --> mkdir cert && cd cert && cp iot_prov.sh
sudo apt install jq -y
sudo apt update -y
sudo apt upgrade -y
#THING NAME (is same as Project Name) and AWS account ID
THING_NAME=$(cat ./iot_prov_config | grep THING_NAME | awk -F'=' '{print $2}')
AccountId=$(cat ./iot_prov_config | grep AWS_AccountId | awk -F'=' '{print $2}')
# create the thing
aws iot create-thing --thing-name ${THING_NAME} | tee create-thing.json
# create and download the keys and device certificate
aws iot create-keys-and-certificate --certificate-pem-outfile ${THING_NAME}-certificate.pem.crt --public-key-outfile ${THING_NAME}-public.pem.key --private-key-outfile ${THING_NAME}-private.pem.key --set-as-active | tee create-keys-and-certificate.json
# attach the certificate to the thing
CERT_ARN=$(jq -r '.certificateArn' < create-keys-and-certificate.json)
aws iot attach-thing-principal --thing-name ${THING_NAME} --principal ${CERT_ARN}
# create the thing policy
policy_stm="\"Statement\": [
{
\"Effect\": \"Allow\",
\"Action\": \"iot:Connect\",
\"Resource\": \"arn:aws:iot:ap-northeast-1:${AccountId}:client/\${iot:Connection.Thing.ThingName}\",
\"Condition\": {
\"Bool\": { \"iot:Connection.Thing.IsAttached\": \"true\" }
}
},
{
\"Effect\": \"Allow\",
\"Action\": \"iot:Publish\",
\"Resource\": \"arn:aws:iot:ap-northeast-1:${AccountId}:topic/\${iot:Connection.Thing.ThingName}/*\"
},
{
\"Effect\": \"Allow\",
\"Action\": \"iot:Subscribe\",
\"Resource\": \"arn:aws:iot:ap-northeast-1:${AccountId}:topicfilter/\${iot:Connection.Thing.ThingName}/count\"
}
]"
aws iot create-policy --policy-name "${THING_NAME}_subscribe" --policy-document "{\"Version\": \"2012-10-17\",${policy_stm}}"
# attach policy to the certificate
aws iot attach-policy --policy-name ${THING_NAME}_subscribe --target ${CERT_ARN}
# download the amazon root ca
wget https://www.amazontrust.com/repository/AmazonRootCA1.pem
# find out what endpoint we need to connect to
echo $(aws iot describe-endpoint --endpoint-type iot:Data-ATS --region ap-northeast-1) >> end_point.json
crontab -r
# creating cron_mod.conf
echo HOST_ENDPOINT=$(jq -r '.endpointAddress' < ./end_point.json) >> cron_mod.conf
echo CACERT=./cert/AmazonRootCA1.pem >> cron_mod.conf
echo CLIENTCERT=./cert/${THING_NAME}-certificate.pem.crt >> cron_mod.conf
echo CLIENTKEY=./cert/${THING_NAME}-private.pem.key >> cron_mod.conf
echo >> cron_mod.conf
echo TOPIC_DETECT="${THING_NAME}/count" >> cron_mod.conf
echo >> cron_mod.conf
echo ACCESS_KEY=$(cat ../.aws/credentials | grep aws_access_key_id | awk -F'= ' '{print $2}') >> cron_mod.conf
echo SECRET_KEY=$(cat ../.aws/credentials | grep aws_secret_access_key | awk -F'= ' '{print $2}') >> cron_mod.conf
echo REGION=$(cat ../.aws/config | grep region | awk -F'= ' '{print $2}') >> cron_mod.conf
echo SENSOR_NO=$(cat ./iot_prov_config | grep SENSOR_NO | awk -F'=' '{print $2}') >> cron_mod.conf
echo S3BUCKET=$(cat ./iot_prov_config | grep S3BUCKET | awk -F'=' '{print $2}') >> cron_mod.conf
echo PREFIX_IN=$(cat ./iot_prov_config | grep PREFIX_IN | awk -F'=' '{print $2}') >> cron_mod.conf
echo TRIGGER_SELECT=$(cat ./iot_prov_config | grep TRIGGER_SELECT | awk -F'=' '{print $2}') >> cron_mod.conf
echo >> cron_mod.conf
echo @reboot ~/.profile >> cron_mod.conf
echo @reboot python ~/main.py >> cron_mod.conf
echo @reboot python ~/emr_rec.py >> cron_mod.conf
# adding .profile
echo >> ../.profile
echo export HOST_ENDPOINT=$(jq -r '.endpointAddress' < ./end_point.json) >> ../.profile
echo export CACERT=./cert/AmazonRootCA1.pem >> ../.profile
echo export CLIENTCERT=./cert/${THING_NAME}-certificate.pem.crt >> ../.profile
echo export CLIENTKEY=./cert/${THING_NAME}-private.pem.key >> ../.profile
echo export >> ../.profile
echo export TOPIC_DETECT=$(cat ./iot_prov_config | grep TOPIC_DETECT | awk -F'=' '{print $2}') >> ../.profile
echo export >> ../.profile
echo export ACCESS_KEY=$(cat ../.aws/credentials | grep aws_access_key_id | awk -F'= ' '{print $2}') >> ../.profile
echo export SECRET_KEY=$(cat ../.aws/credentials | grep aws_secret_access_key | awk -F'= ' '{print $2}') >> ../.profile
echo export REGION=$(cat ../.aws/config | grep region | awk -F'= ' '{print $2}') >> ../.profile
echo export SENSOR_NO=$(cat ./iot_prov_config | grep SENSOR_NO | awk -F'=' '{print $2}') >> ../.profile
echo export S3BUCKET=$(cat ./iot_prov_config | grep S3BUCKET | awk -F'=' '{print $2}') >> ../.profile
echo export PREFIX_IN=$(cat ./iot_prov_config | grep PREFIX_IN | awk -F'=' '{print $2}') >> ../.profile
echo export TRIGGER_SELECT=$(cat ./iot_prov_config | grep TRIGGER_SELECT | awk -F'=' '{print $2}') >> ../.profile
crontab ./cron_mod.conf
次回
(8) template.yamlで定義するAWSリソースの説明とsam deployに続きます。
追記
修正 2022.10.25
IoT policyをRegion、AWSアカウント、topicで明示されたResource名で縛られたpolicyに修正しました。