0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

CloudWatchのAWS操作ログを集計して学習記録を自動生成する仕組みを作った話

Posted at

はじめに

現在フリーランスで活動しているエンジニアです。エンジニア歴は4年目になります。
AWSについては業務で触った経験はあるものの、「マスターしている」と言えるレベルではなく、
特に今回扱う Step Functions / Athena / Glue はほぼ初学習の状態からのスタートでした。

今回、CloudWatchに記録されているAWS操作ログを集計し、「どんなAWS操作をどれくらい行ったか」を学習記録として自動生成する仕組みを構築しました。

使用技術は以下です。

  • Step Functions
  • Lambda
  • Athena
  • Glue
  • S3
  • EventBridge

※ 本記事では「演習中に迷った点」と「それを解決するために調べた技術背景」に焦点を当てます。


迷ったこと①

Step Functions → Lambda → Athenaクエリ実行後、結果を待たずに次へ進んでしまう

何に迷ったか

Step FunctionsからLambdaを呼び出し、
Lambda内でAthenaのクエリを実行していました。

しかし、

  • クエリ実行後すぐ次のステートに進む
  • まだAthenaのクエリが終わっていない
  • 結果が空 or 未確定の状態になりStep Functionsがエラーで止まってしまう

という問題が発生しました。


調べたこと(技術的背景)

Athenaのクエリ実行は 非同期処理 である、という点が重要でした。

AthenaのAPIは主に以下の流れになります。

  1. StartQueryExecution
    → クエリを投げるだけ(完了は待たない)
  2. GetQueryExecution
    → 状態を取得する(RUNNING / SUCCEEDED / FAILED)

つまり、

Lambdaで StartQueryExecution を呼んだ時点では、
クエリは「開始した」だけで「終わっていない」

という仕様でした。

このため
Step Functions側で「完了を待つ仕組み」を作る必要がある
と分かりました。


どう判断したか(設計)

Step Functionsで以下のループ構成を作りました。

  • Wait ステートで数秒待機
  • GetQueryExecutionStatus を実行
  • Choice ステートで状態を判定
    • SUCCEEDED → 次へ
    • FAILEDまたはCANCELLED → エラーとして停止
    • それ以外 → 再度 Wait に戻る

擬似フロー:
StartQuery

Wait

GetQueryExecutionStatus

Choice(完了?)
├ Yes → 次へ
└ No → Waitへ戻る

このようにすることで、

  • Athenaの完了を確実に待つ
  • Step Functionsのステートとして処理が可視化される

というメリットが得られました。


迷ったこと②

Athenaクエリ結果をStep Functions間でどう渡すか

何に迷ったか

Athenaのクエリ結果を

  • 次のステート
  • 次のLambda

に渡す必要がありました。

しかしStep Functionsでは
ステート間で扱えるデータサイズに約256KBの制限があります。

現状そのまま渡しても制限内に収まりそうではあるが、将来的に

  • ユーザー数が増える
  • ログ件数が増える

と、「結果をそのままJSONで渡す」方式では 上限を超える可能性が高いと感じました。


調べたこと(技術的背景)

調べて分かったポイントは以下です。

  • Step Functionsは「大量データの受け渡し」に向いていない
  • 大きなデータは
    • S3
    • DynamoDB
      などの外部ストレージに逃がすのが定石

また、Athenaはもともと

クエリ結果をS3に保存する仕組み

を持っているため、

  • 結果データ → S3
  • Step Functions → S3のパスのみ管理

という設計が自然だと分かりました。


どう判断したか(設計)

  • Athenaの結果はS3に保存
  • Step Functionsでは「S3の保存先パス」だけを受け渡す

構成にしました。

これにより、

  • データ量に依存しない
  • 将来のユーザー増加にも耐えられる

というメリットを得ました。


迷ったこと③

GlueのprojectionとS3のパス構造が噛み合わない問題

何に迷ったか

Athenaでログを取得するため、
Glueのテーブルで partition projection を使用していました。

S3のパス構造の一部に accountid が含まれており、

s3://bucket/logs/accountid=123456789012/...

のような構成でした。

しかし、

  • Glueのprojectionには
    あらかじめ accountid の候補値が登録されている必要がある
  • 新しいaccountidが増えると
    クエリで参照できない

という問題に直面しました。


調べたこと(技術的背景)

Glueのprojectionは

  • 「存在しうるpartitionの値」をメタデータとして定義しておく仕組み
  • 動的にS3をスキャンして自動で増えるわけではない

という仕様でした。

つまり、

S3にデータがあっても
Glueが知らないpartitionは
Athenaから参照できない

という構造です。


どう判断したか(設計)

Step Functionsの最初のステップで、

  1. Glueテーブルに登録されている accountid を取得
  2. S3側に存在する accountid を取得
  3. 差分があれば Glueに登録

という処理を追加しました。

これにより、

  • 新しいaccountidが追加されても自動でGlue側に反映される
  • 全アカウントについてのログを取得するAthenaクエリが成功する

という構成になりました。


まとめ

  • Athenaの非同期性
  • Step Functionsのデータ制限
  • Glue projectionの仕組み

は表面的に使っているだけでは気づきにくい部分でした。

同じように

  • AWSは触ったことがある
  • でもStep FunctionsやAthenaはよく分からない

という方の参考になれば嬉しいです。


使用技術

  • AWS Step Functions
  • AWS Lambda
  • Amazon Athena
  • AWS Glue
  • Amazon S3
  • Amazon EventBridge
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?