Translate

ラベル AWS の投稿を表示しています。 すべての投稿を表示
ラベル AWS の投稿を表示しています。 すべての投稿を表示

2024年9月18日水曜日

既存の複数のEC2インスタンスを毎週月~金の8:58から18:02まで起動させておくCloud Formation定義ファイル

トライアンドエラーを繰り返し表題の定義ファイルをつくった。

ようやく動作したので、グログにのこしておく。

 

 忘備録として:

 

  • AWS EventBridgeを使っている(Lambdaでやる方法もある)
  • イベントバスはdefaultでないとスケジュール化できなかった
  • パラメータでInstanceIdを複数選択させるためにList<AWS::EC2::Instance::Id>を使うとStringに直接できなかったので、(負けた気がするが)Stringで書くことにした
  • 対象のEC2インスタンスはプライベートでもいいが、System Managerを使っているのでエンドポイントかNATでIGWに出ていける設定は必要(このテンプレート対象外)
  • 複数リージョンにまたがるEC2インスタンスは指定できない
  • AWS::Events::RuleにはなぜかTimeZone指定でAsia/Tokyoできなかった

 

AWSTemplateFormatVersion: '2010-09-09'
Description: >
  CloudFormation template for EC2 start/stop scheduling using EventBridge and Systems Manager.

Parameters:
  Project:
    Type: String
    Default: "ai-agent"
    Description: "The project name."
  Environment:
    Type: String
    Default: "demo"
    AllowedValues:
      - "demo"
      - "ita"
      - "itb"
      - "st"
      - "prod"
      - "dpsc"
    Description: "The environment name."
  Version:
    Type: String
    Default: "0.0.12"
    Description: "The version of the stack."
  Instances:
    Type: String
    Description: 'The list of EC2 Instance IDs to be managed. ex) ["i-xxxxxxx", "i-yyyyyyy"]'
  StartSchedule:
    Type: String
    Default: "cron(58 23 ? * Sun-Thu *)"
    Description: "Cron expression for the EC2 start schedule (UTC)."
  StopSchedule:
    Type: String
    Default: "cron(32 8 ? * Mon-Fri *)"
    Description: "Cron expression for the EC2 stop schedule (UTC)."

Resources:

  # IAM Role for EventBridge to interact with Systems Manager
  EC2StartStopRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub "${Project}-${Environment}-${Version}-ec2-start-stop-role"
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: events.amazonaws.com
            Action: "sts:AssumeRole"
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AmazonSSMAutomationRole
      Tags:
        - Key: Project
          Value: !Ref Project
        - Key: Environment
          Value: !Ref Environment
        - Key: Version
          Value: !Ref Version

  # Start Rule for EC2
  StartRule:
    Type: AWS::Events::Rule
    Properties:
      Name: !Sub "${Project}-${Environment}-${Version}-ec2-start-rule"
      ScheduleExpression: !Ref StartSchedule
      EventBusName: default
      Targets:
        - Arn: !Sub "arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:automation-definition/AWS-StartEC2Instance"
          RoleArn: !GetAtt EC2StartStopRole.Arn
          Id: StartTarget
          Input: !Sub '{"InstanceIds": ${Instances}}'


  # Stop Rule for EC2
  StopRule:
    Type: AWS::Events::Rule
    Properties:
      Name: !Sub "${Project}-${Environment}-${Version}-ec2-stop-rule"
      ScheduleExpression: !Ref StopSchedule
      EventBusName: default
      Targets:
        - Arn: !Sub "arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:automation-definition/AWS-StopEC2Instance"
          RoleArn: !GetAtt EC2StartStopRole.Arn
          Id: StopTarget
          Input: !Sub '{"InstanceIds": ${Instances}}'


Outputs:
  StartRuleName:
    Description: "The name of the EventBridge rule for EC2 start."
    Value: !Ref StartRule
  StopRuleName:
    Description: "The name of the EventBridge rule for EC2 stop."
    Value: !Ref StopRule
  IAMRoleName:
    Description: "The IAM role used by EventBridge for EC2 start/stop automation."
    Value: !Ref EC2StartStopRole

 

ちなみにこのCloudFormation定義をつくるのにLLM Chatモデル yi-coder でやり取りをひたすらしていたが、結構粘ってもLLMは完璧な正解を返してはくれなかった(InstanceIdの配列のところは、人力で完成させざるを得なかった)。


コード専門LLMでもかけないCloudFormation..難易度高いなあ..

 

以上

2020年6月17日水曜日

aws-iot-device-sdk-js を使っている人へ



こんなトラップに引っかかるのは
私だけかもしれませんが..



AWS IoT Core をJavaScriptから使いたくて

(2020/6/17 本記事執筆段階の)公式ドキュメント

AWS IoT Device SDK for JavaScript をインストールする
https://docs.aws.amazon.com/ja_jp/iot/latest/developerguide/iot-device-sdk-node.html


にかかれている

git clone https://github.com/aws/aws-iot-device-sdk-js.git

を実行して JavaScript SDK をつかっていた。


実は
この記事を書く1年前ほどから
この JavaScript SDK を使っていたのだけど、

なんとなく
機能がしょぼいなあ..
とか
デバイスシャドウを使うとき
pub/subするためのデバイスのコネクションが一旦切れる
(デバイスシャドウを使い終わるとreconnectする)
なあ..
とか
なんか洗練されていないなあ
ださいなあ..


とおもいながら
使っていた。

で、
昨日重大なことに気づいた。

先程書いた GitHub サイトを
ブラウザで開くと
README.mdの先頭に


New Version Available
A new AWS IoT Device SDK is now available. It is a complete rework, built to improve reliability, performance, and security. We invite your feedback!

This SDK will no longer receive feature updates, but will receive security updates.



..


....


.....最新バージョンじゃないじゃん....


しかも
最新バージョンは
別のリポジトリだと...


公式ドキュメント(これを書いている時点)も
ふるいほうのリポジトリじゃん..

公式ドキュメントの手順だと
このサイトのREADME.mdひらかず
いきなり git clone しろって
書いてあるじゃん..




v2のリポジトリはこちら

[GitHub] aws/aws-iot-device-sdk-js-v2
https://github.com/aws/aws-iot-device-sdk-js-v2




p.s.

v2のサンプル、読みづらい。

jsってかいてるけど
TypeScriptでサンプル書かれてるし..
しかも非同期 async や Promise つかってるし..
yield とかつかってるし..
リファレンスマニュアル全然読みにくいし..


つかってもらおうっていう
おもてなしの心が
まったく感じられん...


2019年12月10日火曜日

AWS Greengrass チュートリアル「機械学習の推論を実行する」を試したが何の反応もなかった件

AWS Greengrassのチュートリアルを試している。

チュートリアルの一つ

機械学習の推論を実行する
https://docs.aws.amazon.com/ja_jp/greengrass/latest/developerguide/ml-inference.html

は、
S3上にあるmxnetモデルファイルをロードしてAWS Greengrass Core(デバイス側)上のLambdaで実行してデバイスに装備したカメラで撮影した対象物を予測しその結果を"hello/world"というトピックに返却するというもの。

下の図のSage Maker部分は、チュートリアルでは体験できないが、S3に学習済みモデルファイルをおいてそれをCore上のLambdaが使用するとことは体験できる。



AWS Greengrass Coreは最近買ってきたRaspberry Pi 4B(3B+でも可)にインストールして、上記リンクのとおりに実行してみた...が、動かない..

AWS Greengrass Core 上のログ(エラー)は /greengrass/ggc/var/log/user/<リージョン名>/NNNNNNNNNN/.log というテキストファイルに書き出される。

のぞいてみると

[2019-12-09T07:45:30.002Z][FATAL]-lambda_runtime.py:140,Failed to import handler function "greengrassObjectClassification.function_handler" due to exception: libgfortran.so.3: cannot open shared object file: No such file or directory
[2019-12-09T07:45:30.004Z][FATAL]-lambda_runtime.py:380,Failed to initialize Lambda runtime due to exception: libgfortran.so.3: cannot open shared object file: No such file or directory


というエラーが出ていた。

どうも libgfortran.so.3 というファイルがない、findで探してみると libgfortran.so.5 はあるけど 3 はなかった。

..で、apt install でインストールしようとすると..

pi@gateway:~ $ sudo apt install libgfortran3
Reading package lists... Done
Building dependency tree
Reading state information... Done
You might want to run 'apt --fix-broken install' to correct these.
The following packages have unmet dependencies:
 python-opencv : Depends: python-numpy (>= 1:1.16.0~rc1) but it is not going to be installed
                 Depends: python-numpy-abi9
 python-picamera : Depends: python-numpy but it is not going to be installed
 python-scipy : Depends: python-numpy (>= 1:1.16.0~rc1) but it is not going to be installed
                Depends: python-numpy-abi9
E: Unmet dependencies. Try 'apt --fix-broken install' with no packages (or specify a solution).
pi@gateway:~ $

..どうもnumpyが悪さしている様子..

ここはpipでなくaptでnumpyをいれてみようということで sudo apt install python-numpy を実行して動かしてみたら、今度はログに


:
[2019-12-10T01:51:58.67Z][ERROR]-[01:51:58] /work/mxnet/src/engine/engine.cc:55: MXNet start using engine: NaiveEngine
[2019-12-10T01:51:59.829Z][ERROR]-csr.py:15,ImportError
[2019-12-10T01:51:59.836Z][ERROR]-csr.py:15,:
[2019-12-10T01:51:59.843Z][ERROR]-csr.py:15,No module named _multiarray_umath
[2019-12-10T01:52:01.69Z][FATAL]-lambda_runtime.py:140,Failed to import handler function "greengrassObjectClassification.function_handler" due to exception: numpy.ufunc size changed, may indicate binary incompatibility. Expected 124 from C header, got 112 from PyObject
[2019-12-10T01:52:01.691Z][FATAL]-lambda_runtime.py:380,Failed to initialize Lambda runtime due to exception: numpy.ufunc size changed, may indicate binary incompatibility. Expected 124 from C header, got 112 from PyObject

  • _multiarray_umath がないよというERROR
  • numpy.ufunc サイズが違うよというFATAL

という2つの問題が発生..


そうか、mxnetがtensorflowを使ってるけど、まだインストールされてなかった。

あわてて sudo pip install tensorflow を実行。


:
  copying h5py/tests/test_vds/test_highlevel_vds.py -> build/lib.linux-armv7l-2.7/h5py/tests/test_vds
  running build_ext
  ('Loading library to get version:', 'libhdf5.so')
  error: libhdf5.so: cannot open shared object file: No such file or directory
  ----------------------------------------
  ERROR: Failed building wheel for h5py
  Running setup.py clean for h5py
Successfully built absl-py wrapt keras-applications termcolor gast
Failed to build h5py
Installing collected packages: funcsigs, mock, absl-py, keras-preprocessing, futures, setuptools, protobuf, grpcio, markdown, werkzeug, tensorboard, wrapt, backports.weakref, h5py, keras-applications, astor, termcolor, gast, google-pasta, tensorflow-estimator, tensorflow

今度は libhdf5.so がないよ..だと..

イライラしつつ sudo apt install libhdf5-dev を実行して、再度hello/worldをサブスクライブしても反応なし..

ログには、

:
[2019-12-10T04:58:46.477Z][FATAL]-lambda_runtime.py:140,Failed to import handler function "greengrassObjectClassification.function_handler" due to exception: numpy.ufunc size changed, may indicate binary incompatibility. Expected 124 from C header, got 112 from PyObject
[2019-12-10T04:58:46.478Z][FATAL]-lambda_runtime.py:380,Failed to initialize Lambda runtime due to exception: numpy.ufunc size changed, may indicate binary incompatibility. Expected 124 from C header, got 112 from PyObject
[2019-12-10T04:58:46.479Z][ERROR]-[04:58:46] /work/mxnet/src/engine/engine.cc:55: MXNet start using engine: NaiveEngine
[2019-12-10T04:58:48.045Z][ERROR]-csr.py:15,ImportError
[2019-12-10T04:58:48.052Z][ERROR]-csr.py:15,:
[2019-12-10T04:58:48.059Z][ERROR]-csr.py:15,No module named _multiarray_umath

..そうか _multiarray_umath の問題を解決できてなかった..

しらべると numpy を最新版にしないといけないらしい。

が、numpy は mxnet の制約上限バージョンでインストールされている..

ままよ、と sudo pip install numpy -U して最新版に更新、Coreデバイスをリブートして、hello/worldをサブスクライブしてみたら..やっと動いた...


うーむ、
AWS Greengrass Core上で動かす Lambda は
AWS上で動かすLambdaと違って
自前で環境を整えないといけない。

現時点のGreengrass CoreはPython2.7なのが厄介だ。

来年には切れる2のサポート問題から、最近のコードは基本 Python3.xで書かれている。

実行ユーザが ggc_user/ggc_group なので、
このユーザにvirtualenvを切ればおそらくPython3.xでも動かせるだろうが、デフォルトの状態ではvirtualenvなしのOSインストール状態のPythonバージョンが適用される。

Raspberry PiのTensorflowも現時点pipできるバージョンは1.14.0。

おまけにエラーは、 /greengrass/ggc/var/log/user/<リージョン名>/NNNNNNNNNN/.log を覗かないとわからない..




そしてもっとも厄介なのが、この情報がいま時点では、ということ。
明日には変わっているかもしれない..

AWS Greengras Core 環境整備がとても大変だ..

本番だとCoreを複数立てるわけだろうし..

かなり厄介だな、IoT ゲートウェイって..



ps 2020/02/18追記

ROSのインストールをはじめて
最新バージョンであるmelodicですらいまだpython2.7を使っていることに気づいてから..
ずっともやもやしてたけど..

やっぱりAWS Greengrass は ROS のソースコードをパクっているんだろうなあ..

いや、ROSのライセンスはBSDだったはずなので、駄目というわけではないのだけど..

ROS モジュールをAWSコンソールからインストールできるからいいのだけどね..

2019年11月28日木曜日

node環境でaws-iot-device-sdk-jsを使っていたら、Emitted 'error' event on DeviceClient instanceと出て落ちる件

node環境でaws-iot-device-sdk-jsをつかったexpressアプリを作って起動したら、

(env) foo@bar:~/tar $ node server.js
Node.js is listening to PORT:3000
connect
events.js:187
      throw er; // Unhandled 'error' event
      ^

Error: premature close
    at onclosenexttick (/home/pi/projects/donkey_agent_telemetry/node_modules/end-of-stream/index.js:54:86)
    at processTicksAndRejections (internal/process/task_queues.js:75:11)
Emitted 'error' event on DeviceClient instance at:
    at MqttClient. (/home/pi/projects/donkey_agent_telemetry/node_modules/aws-iot-device-sdk/device/index.js:772:15)
    at MqttClient.emit (events.js:215:7)
    at TLSSocket.f (/home/pi/projects/donkey_agent_telemetry/node_modules/once/once.js:25:25)
    at onclosenexttick (/home/pi/projects/donkey_agent_telemetry/node_modules/end-of-stream/index.js:54:73)
    at processTicksAndRejections (internal/process/task_queues.js:75:11)
(env) foo@bar:~/tar $


..というエラーがでた..

'error' イベントがemitされたらしいので

device.on('error', function() {
  console.log('error');
})

を使って例外を無視させようとしたけど、
同じエラーが発生..

どうもほかのイベントすべてを
うけとってやらないとエラーでnodeが落ちるらしい。

device.on('reconnect', function() {
  console.log('reconnect');
})

device.on('close', function() {
  console.log('close');
})

device.on('offline', function() {
  console.log('offline');
})

全部のイベントをうけとるようにしたら、
落ちなくなった...

それだけ。

2019年4月11日木曜日

AWS IoT Core にQoS=2でLast Willメッセージを設定したら例外が出た件

AWS IoT CoreへアクセスするPythonプログラムを書いた。
ライブラリはpahoではなくAWSIoTPythonSDKを使った。



ちなみにMQTTブローカへ接続するプログラムを書く場合、
ベンダ提供ライブラリを素直に使うのが生産性を上げるコツだ。
ベンダ固有の機能の有無を関数やメソッドのコード上ドキュメントで
確認できるし、
一番困るのがベンダ固有のpayloadやtopicフォーマットを持っている
場合だ。
ドキュメントをイチから読むより、関数やメソッドのドキュメントを
見るほうが圧倒的に速い..と私はおもっている。
..Eclipse Mosquitto、IBM Watson IoT PlatformとAWS IoT Coreしか
まだ触ったことがないのだけど..

話をもどすが、どうも AWS IoT に Will

つまりデバイスが死んだ際に
特定のメッセージを指定トピックへ送信してくれる
MQTTベースのメッセージブローカに標準搭載される機能

がないと思っている人が意外と多い。

AWS IoT に Will がないと書かれたブログ記事もすくなくなく
これを鵜呑みにした人がおおいのだろう。

ベータ版の頃はそうらしかったのだけど、
今のバージョンでは存在している。
#この先、消えるかはわからないけど ;-p

AWSIoTPythonSDK の AWSIoTMQTTClient クラスには

configureLastWill(topic, payload, QoS, retain=False)
というインスタンスメソッドが存在する。

なのでQoS=2にしてWillメッセージをセットすると..

Traceback (most recent call last):
  File "test_dev.py", line 45, in
    test_dev()
  File "test_dev.py", line 31, in test_dev
    client = Client('conf/aws/xxxx/xxxx.yml', 'xxxx_test')
  File "C:\Users\xxxxx\projects\xxxx\aws\broker.py", line 354, in __init__
    client.connect()
  File "C:\Users\xxxxx\AppData\Local\Continuum\anaconda3\envs\xxxx\lib\site-packages\AWSIoTPythonSDK\MQTTLib.py", line 486, in connect
    return self._mqtt_core.connect(keepAliveIntervalSecond)
  File "C:\Users\xxxxx\AppData\Local\Continuum\anaconda3\envs\xxxx\lib\site-packages\AWSIoTPythonSDK\core\protocol\mqtt_core.py", line 195, in connect
    raise connectTimeoutException()
AWSIoTPythonSDK.exception.AWSIoTExceptions.connectTimeoutException


というエラーになってconnectできない状態になってしまった。

どうも Will はサポートされたけど、
AWS IoT はあくまで QoS は 0 か 1 までで
QoS=2は未だにサポートしていないらしい..
というより、今サポートしてないなら、やる気なしでしょ..


ということでQoS=1にしたら正常に動作した。


ちなみに引数にretainがあり、
AWSIoTPythonSDKのコードをおっていくとpahoのクライアントクラスに
そのまま値を渡しているので、
もしかしたら..とおもって retain=True で実行してみた。

..結果は、QoS=2のときと全く同じ例外が発生してしまった..

retain とは、
最後にpublishされたメッセージをブローカで保持し、
新規Subscriberにそのメッセージを渡す
MQTTベースのメッセージブローカに標準提供される機能のひとつ。

AWS IoTベータのころからサポートされておらず、
こちらもQoS=2同様
現時点でもサポートされていない
ということらしい..


そのかわりにシャドウを使えってことなのだろうけど..
この機能AWS IoT Coreにしか存在しない独自機能なんだよなあ..

..日本のSIerは、こういったベンダ依存をきらうからねえ..

2019年4月3日水曜日

AWS IoT Core へバイナリデータが送れない件(AWS IoT CoreをDonkey Carで使う)

Donkeycar のAI処理が重くなりすぎたので、サーバ側で処理させようとMQTTブローカ経由で画像データをおくっていたのだけど、AWS環境でもやってみたいということで試してみた。

AWS IoT Coreをセットアップして、paho-mqttを使って画像データを送信しようとしたのだけどうまくいかない..

AWS IoT Python SDK を使ってもうまく送れない..


Eclipse Mosquitto や IBM Watson IoT Platform だとうまくいったのに..



..と、いろいろ調べていると以下の記事


Python AWS IoT SDK - MQTT publish with binary payload fails
https://forums.aws.amazon.com/thread.jspa?threadID=237466


にこのような記述があった。

The AWS IoT Python SDK uses Eclipse Paho Python MQTT Client as the dependency underneath. It supports the following payload type in Python:
1. str
2. bytearray
3. unicode string

(日本語訳)
AWS IoT Python SDKは、その下の依存関係としてEclipse Paho Python MQTTクライアントを使用します。 Pythonでは次のペイロードタイプをサポートしています。
1. str
2. bytearray
3. Unicode文字列

..ん?
bytesがサポートされていない?!


仕様かよ!!






bytearray(message) したら..動いた..

マジかよ..subscribe側でbytesに戻さないと..


p.s.1

AWS IoT CoreはWatson IoT Platformより画面が整理されていて使いやすい。
..のだけど、パラメータが多いし、Raspberry Pi側にプライベートキーファイルとcertificateファイル、サーバ側のルートCAファイルをおいてやらないといけないのが面倒だ..

モノのシャドウはいわゆるMQTTブローカのWill機能。AWS IoTCore上でドキュメントを定義して、これをMQTT通信経由でget/delete/update/deltaイベントコールバックで操作する。
便利そうではあるのだけど、ドキュメントがJSONデータ1つなんだよなあ..

まあキューにすればMQの悪名高きデッドレターキュー管理シないといけなくなるしなあ..



p.s.2

にしても..各ベンダのMQTTブローカって独自色を出そうと付加機能つけすぎ..
正直 paho-mqtt ライブラリで疎通取るより各ベンダ独自のSDK使ったほうが、生産性がとっても高くなることがよくわかった..
#SDKで方言対応してくれるからね

このあたり、基盤屋が対応してくれればいいのだけど、堅モノから一歩たりとも出てくれない..

せめて..死んで^H^H^H python覚えてくれないかなあ..

Google Colab相当の環境をローカルPC上のDocker Composeで実現する

 Docker Composeの有料版に、お金を払いたくない ^H^Hが使えない ため古いゲーミングPC(GeForce3080)にDocker Composeを入れてその上のコンテナでGoogle Colab相当のノート操作ができないかためしてみた: コンテナイメージとして a...