kakakakakku blog

Weekly Tech Blog: Keep on Learning!

データエンジニアリングライフサイクルのステージと底流とは /「データエンジニアリングの基礎」を読んだ

2024年3月に出版された「データエンジニアリングの基礎」を読んだ📕

仕事で取り組んでいることに関係していて,何かしら新しい気付きや発見があれば良いな〜と思って読んでみたけど,期待以上に素晴らしい一冊だった❗️データを取り扱うときに考慮すべきポイントが詳細にまとまっていて,一人で読むのもヨシ!データプロジェクトのメンバーと輪読会をして改善点を洗い出すのもヨシ!という感じで幅広く活用できると思う.

特に本書で重要なのは「データエンジニアリングライフサイクル」というフレームワーク(コンセプト)で,データを活用してプロダクトの価値に変えていくための「ステージ」「底流」から構成されている👌(図を引用できると紹介しやすいんだけど...!)特にデータエンジニアリングライフサイクルのあらゆる側面をサポートする横断的な観点を本書では「底流 (undercurrents)」と表現していて,以下の6種類から構成されていた.本書は全体を通して,データエンジニアリングライフサイクルの観点から解説されていて印象的だった.

  • セキュリティ
  • データ管理
  • DataOps
  • データアーキテクチャ
  • オーケストレーション
  • ソフトウェアエンジニアリング

技術的利害関係者

1章にデータエンジニアに関連する技術的利害関係者の紹介が出てくる.また11章の「職種名と担当範囲は変化する」では担当範囲の境界はますます曖昧になっているとも書いてある.データエンジニアリングライフサイクルを実現するために多くの役割が必要になることは理解できるけど,ある程度の企業規模じゃないとそこまで専任を置くことは難しく,今いるメンバーでどうオーバーラップして前に進めていくかを考えることも重要なのかなと個人的には思った😀また役割のトピックを読んでいて,AWS Well-Architected Machine Learning Lens の「MLOE-04: Establish ML roles and responsibilities」を思い出した.同じく Machine Learning Lens でも役割と責任の分離は明確ではなくオーバーラップすると書いてある.どういう役割が必要なのかを把握することはとても重要❗️

docs.aws.amazon.com

データエンジニアが ML について知っておくべきこと

役割という観点だと,9章で紹介されていた「データエンジニアが ML について知っておくべきこと」というトピックも良かった😃僕自身はアプリケーション・インフラ・DevOps(定義は曖昧だけど)など,ソフトウェア開発に必要なある程度の領域を幅広く得意としているけど,機械学習 (ML) の専門性はなく,ちょうど苦戦しているところだった.

もちろん本書の「まえがき」にデータサイエンティストでは対処できない問題があると書いてある通り,データエンジニアリングライフサイクルを実現するためには特に底流まわりを支援する必要があって,僕自身のスキルセットはフィットしそうだけど,さらに僕自身が機械学習 (ML) の理解を深めることでプロジェクトの価値にさらに貢献できるかなと思っていた.とは言え,どこまで深く理解するべきなのか・そもそも理解できるのかという不安もあり,まずは本書に載っている「知っておくべきこと」の中から理解が浅いところを抑えておきたいなと感じた.

良いデータアーキテクチャの原則

3章に出てくる「良いデータアーキテクチャの原則」は AWS Well-Architected Framework や Google Cloud の 5 Principles for Cloud-Native Architecture にインスパイアされたと書いてあったけど,データエンジニアリングに限らず重要な観点で,紹介されていて良かった👏 逆に普段からソフトウェア開発をしながらこういう原則を意識できていれば,データプロジェクトでも応用しやすいと思う.あと原則7に Jeff Bezos の「Two-Way Door(双方向ドア)」という表現が紹介されていたのもなつかしくて良かった❗️

  • 原則1: 共通コンポーネントを賢く選択する
  • 原則2: 障害に備える
  • 原則3: スケーラビリティ設計
  • 原則4: アーキテクチャはリーダーシップだ
  • 原則5: 常に設計し続ける
  • 原則6: 疎結合システムを構築する
  • 原則7: 可逆な決定をする
  • 原則8: セキュリティを優先する
  • 原則9: FinOps を活用する

aws.amazon.com

読書メモ

他に読書メモに残したことの一部を箇条書きにしておく❗️

  • タイプAデータエンジニアとタイプBデータエンジニア
  • CAO (Chief Analytics Officer): 最高分析責任者
  • CAO-2 (Chief Algorithms Officer): 最高アルゴリズム責任者
  • リバース ETL
  • DMBOK (Data Management Body of Knowledge)
  • The DataOps Manifesto
  • 履歴書駆動開発 (Resume Driven Development)
  • ゼロスケール (Scale to Zero)
  • データカスケード
  • アプリケーションと ML 間での緊密なフィードバック

誤植

  • P13: DMM (Data Management Maturity) のリンクが 404 になっていた
  • P23: 図1-12 の データアーキテクチャデータアーキテクト では?(原著では Data architects と書かれていた)

X ポスト🔗

AWS Chatbot で AWS Lambda 関数の集約したロググループからログを取得する

AWS Lambda 関数の Errors メトリクスなどを Amazon CloudWatch Alarm でモニタリングして,エラー発生時に Amazon SNS と AWS Chatbot を組み合わせて Slack に通知すると Show error logs ボタンと Show logs ボタンが表示される✅ そして AWS Chatbot に権限を与えておくと,Amazon CloudWatch Logs から関連したログを Slack 上で取得できる.エラー発生時に迅速にエラー詳細を把握できるのは便利だと思う👌

Amazon CloudWatch Logs ロググループに注意する

便利な Show error logs ボタンと Show logs ボタンは AWS Lambda 関数のデフォルトの Amazon CloudWatch Logs ロググループ /aws/lambda/xxx を前提に作られている点は注意しておくと良いと思う.ドキュメントには直接明記されていなかった(見つけられなかった)けど,挙動からそう判断した.

具体的には,2023年11月にリリースされた AWS Lambda 関数の「高度なログ制御機能」を活用して,任意の Amazon CloudWatch Logs ロググループに集約している AWS Lambda 関数でボタンを押すと I can't get the logs for the CloudWatch Alarm sandbox-errors-alarm for you because I cannot find the log group /aws/lambda/sandbox for sandbox. というエラーが出て使えなかった(sandbox-errors-alarm は Amazon CloudWatch Alarm 名 / sandbox は AWS Lambda 関数名).

aws.amazon.com

@aws コマンドを使う

ボタンを押すよりも面倒ではあるけど,ワークアラウンドとして Slack 上で直接 @aws logs filter-log-events コマンドを実行すれば,簡易的に AWS Lambda 関数のエラー詳細を把握できる.AWS Chatbot から You can also run the query directly using the following command としてコマンド例を出してくれていたため,参考にしながら作ってみた.

ポイントを箇条書きで載せておく📝

  • --log-group-name に Amazon CloudWatch Logs ロググループを指定する
  • --log-stream-name-prefix に Amazon CloudWatch Logs ログストリームを指定する
  • --start-time--end-time に Unix Timestamp (Milliseconds) を指定する
@aws logs filter-log-events --region ap-northeast-1 --log-group-name aggregated-function-logs --log-stream-name-prefix 2024/04/12/sandbox[$LATEST] --start-time 1712883000000 --end-time 1712883300000

その他のオプションも活用する場合は CLI ドキュメントを参考で👌

awscli.amazonaws.com

そして @aws コマンドを使って AWS Chatbot 経由でログを取得できた.

まとめ

AWS Lambda 関数で任意の Amazon CloudWatch Logs ロググループに集約してる場合は Slack 上で AWS Chatbot の Show error logs ボタンと Show logs ボタンが使えず,今回は @aws コマンドを使ってワークアラウンドを試してみた.とは言え,正直エラー発生時に @aws コマンドを作るのは面倒ではあるため,本格的に実現するなら「カスタム Lambda アクション (Custom Lambda Action)」を実装する必要がありそう.あと @aws コマンドの引数が多くなければ「カスタム CLI アクション (Custom CLI Action)」を使う案もありそう.

docs.aws.amazon.com

docs.aws.amazon.com

関連記事

kakakakakku.hatenablog.com

PyTorch Tutorials「(optional) Exporting a Model from PyTorch to ONNX and Running it using ONNX Runtime」を試した

PyTorch のチュートリアル「(optional) Exporting a Model from PyTorch to ONNX and Running it using ONNX Runtime」を試した❗️

pytorch.org

PyTorch に低解像度の画像を高解像度の画像に変換する「超解像モデル」のサンプルがあって,今回のチュートリアルではそのモデルを ONNX (Open Neural Network eXchange) にエクスポートして,ONNX Runtime で推論する流れをサクッと体験できる.完全に入門者の僕にピッタリの内容だった👌

github.com

学べたこと

PyTorch のモデルは torch.onnx.export() 関数で ONNX にエクスポートできる.

pytorch.org

そして onnxruntime.InferenceSession クラスの run() 関数で推論できる.今回のチュートリアルでは providersCPUExecutionProvider を指定しているけど,CUDA (Compute Unified Device Architecture) 環境があれば CUDAExecutionProvider を指定することもできる.

ort_session = onnxruntime.InferenceSession("super_resolution.onnx", providers=["CPUExecutionProvider"])

onnxruntime.ai

実行結果

PyTorch モデルを ONNX モデルにエクスポートしてから推論した.今回は猫画像🐱を超解像にする内容だった.

実行前

実行後

その他

チュートリアルの範囲外ではあるけど,Netron を使うと ONNX モデルを可視化できる.

netron.app

今回エクスポートした super_resolution.onnx を可視化してみた💡

関連チュートリアル

pytorch.org

Amazon API Gateway の Lambda オーソライザーで "User is not authorized to access this resource" と出たら

Amazon API Gateway の Lambda オーソライザー(旧カスタムオーソライザー)を使ってアクセス制御をするときに,Authorization ヘッダーは正しいはずなのに {"Message":"User is not authorized to access this resource"} というエラーが出てしまう場合,Lambda オーソライザーの設定「認可のキャッシュ (Authorization caching)」に関係してる場合がある💡

前提

今回はサンプルとして Amazon API Gateway に /users リソースを追加して POSTGET をサポートする.そしてどちらにも Lambda オーソライザー(トークンタイプ)によるアクセス制御を設定しておく👌

/users (POST)
/users (GET)

そして,Lambda オーソライザーの実装はドキュメントに載っている Python のサンプルコードをそのまま使う📝実装としては簡易的で Authorization ヘッダーに allow と設定すれば OK という仕組みになっている.

docs.aws.amazon.com

ポイントはこの Lambda オーソライザーの実装では以下のようなポリシーが生成されるところ💡(POST の場合)

Allow

{
    "principalId": "user",
    "policyDocument": {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Action": "execute-api:Invoke",
                "Effect": "Allow",
                "Resource": "arn:aws:execute-api:ap-northeast-1:111111111111:xxxxxxxxxx/Prod/POST/users"
            }
        ]
    },
    "context": {
        "stringKey": "stringval",
        "numberKey": 123,
        "booleanKey": true
    }
}

Deny

{
    "principalId": "user",
    "policyDocument": {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Action": "execute-api:Invoke",
                "Effect": "Deny",
                "Resource": "arn:aws:execute-api:ap-northeast-1:111111111111:xxxxxxxxxx/Prod/POST/users"
            }
        ]
    },
    "context": {
        "stringKey": "stringval",
        "numberKey": 123,
        "booleanKey": true
    }
}

動作確認

Amazon API Gateway の /users リソースに POST リクエストを送信した後すぐに GET リクエストを送信する.すると {"Message":"User is not authorized to access this resource"} というエラーが返ってくる🔥キャッシュの仕組みを理解してないと「なぜー?」となってしまう.キャッシュの TTL はデフォルトで「300秒」に設定されている👀

$ curl -X POST -H 'Authorization: allow' ${ENDPOINT}/users
$ curl -X GET -H 'Authorization: allow' ${ENDPOINT}/users
{"Message":"User is not authorized to access this resource"}

対策

選択肢は大きく2つあると思う👌

選択肢1

Lambda オーソライザーで生成するポリシーの条件を緩和する選択肢がある.AWS re:Post の記事にも Resource/*/* にすれば OK という解決策が紹介されている💡もちろんワイルドカードで許可できない場合もあると思うし,最小権限の原則を考慮すると闇雲にワイルドカードっていう判断が危険なこともあると思う.

repost.aws

ちなみに前に紹介記事を書いた Powertools for AWS Lambda (Python)Event Source Data ClassesAPIGatewayAuthorizerResponse を使ってポリシーを生成する場合,allow_all_routes() を使うと以下のようにワイルドカードでポリシーが生成される.allow_route() を使うと HTTP メソッド・リソースを細かく指定できる.

{
    "principalId": "user",
    "policyDocument": {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Action": "execute-api:Invoke",
                "Effect": "Allow",
                "Resource": "arn:aws:execute-api:ap-northeast-1:111111111111:xxxxxxxxxx/Prod/*/*"
            }
        ]
    }
}

kakakakakku.hatenablog.com

選択肢2

次にキャッシュの TTL を短くする(もしくはキャッシュを無効化する)選択肢がある.キャッシュによる影響はなくなるけど,毎回 Lambda オーソライザーを呼び出すことになるため,パフォーマンスなどの観点で検討が必要になる.

デフォルトで 300 秒、API 所有者が 0~3600 の範囲で設定可能。

docs.aws.amazon.com

CloudFormation の IaC ジェネレーター機能をサクッと試せる「IaC Generator Workshop」

2024年2月にリリースされた AWS CloudFormation の「IaC ジェネレーター機能」を使うとマネジメントコンソール・AWS CLI などを使って作った(作ってしまった)リソースをスキャンして,自動的に AWS CloudFormation テンプレート化 (YAML / JSON) できる❗️もちろんそのまま AWS CloudFormation スタックにリソースをインポートすることもできる.

aws.amazon.com

今までも AWS CloudFormation のインポート機能はあったけど,リソース設定と見比べながら(そしてドリフト機能を活用しながら)テンプレートを書くのはそこそこ大変さがあったと思う.IaC ジェネレーター機能を使う流れは以下のブログにも載っていて,今回紹介するワークショップの内容にも似ている👀

aws.amazon.com

IaC Generator Workshop

この IaC ジェネレーター機能をサクッと試せるワークショップ「IaC Generator Workshop」も公開されていて,試してみた💡

実は2024年2月にワークショップも公開されていて,すぐに試そうと思ったけど,環境セットアップで使うスクリプト infrastructure-script.sh にアクセスすると Access Denied になってしまっていて進めなかった.1ヶ月ほど定期的に確認しても直ってなくて諦めていたけど,最近確認したら修正されていたので,改めてワークショップの内容を確認しておくことにした.

catalog.workshops.aws

ワークショップの内容としては,Amazon VPC 関連リソースと Amazon EC2 インスタンスをスクリプト (AWS CLI) で作って,リソースを AWS CloudFormation の「IaC ジェネレーター機能」でテンプレート化する.以下はスクリプトを実行したときに出力されたリソース情報一覧(既に削除済).

These are the resources created, you will need these ids later in the workshop.
Key Pair:  iacgenerator
VPC ID: vpc-00e0e3957e53ef021
Subnet ID: subnet-05a5cc381ac3dcce6
Internet Gateway ID: igw-0e98de8f97252af56
Route Table ID: rtb-0cff1f90fa8f83671
Security Group ID: sg-0c5db16219d23efd4
Instance ID: i-0c543696db799acf8

そして IaC ジェネレーター機能では,選択したリソースに関連するリソースも自動的に含めることができる.今回のワークショップだと AWS::EC2::NetworkAclAWS::EC2::SubnetNetworkAclAssociation などは「関連リソース」に含まれていた.

IaC Generator Workshop: テンプレート化

ちなみにテンプレート化したときに「リソース警告」も出ていた.AWS::EC2::InstanceAWS::EC2::Subnet など IaC ジェネレーター機能でサポートしてるリソースでもプロパティレベルでサポート対象外になっていることもありそうだった.このあたりは影響が出るかどうか確認しつつ,必要ならテンプレートを編集してからインポートすることもできる👌

docs.aws.amazon.com

IaC Generator Workshop: リソース警告

そして,最後はテンプレートをそのまま AWS CloudFormation スタックにインポートする.ちなみに今回のワークショップではテンプレート化するときに DeletionPolicy: Delete を指定するようになっているため,ワークショップ終了後のお掃除はインポートしたスタックを削除すれば良いという流れになっていた(ちなみに僕の環境だと一部の VPC リソースが削除失敗になってしまった💨).

IaC Generator Workshop: リソースをインポート

まとめ

もしまだ AWS CloudFormation の IaC ジェネレーター機能を試してなくて気になっていれば,1時間以内でサクッと終わるワークショップ「IaC Generator Workshop」がおすすめ❗️

関連ドキュメント

docs.aws.amazon.com