SORACOM UG Hiroshima #10の反省を活かし、ハンズオン用アップローダをAmplify Gen2で作り直した

AWS

はじめに

おつかれさまです。tyamonです。

SORACOM UG Hiroshima #10(2025年9月20日開催)のハンズオンパートで出た反省をもとに、スマホで撮った写真をSORACOM Harvest Filesへ送るアップローダアプリを、今回のSORACOM UG Explorer 2026(2026年10月31日開催)向けに作り直しました。この記事では、何を変えたか、なぜそうしたかをまとめます。

結論:インフラはAmplify Gen2でコード化し、画像はブラウザ側で縮小してから送る構成にしました。


UG Hiroshima #10のときは、AWSリソースを全部手動で作っていた

UG Hiroshima #10版は、Cognito、Lambda、API Gateway、S3、CloudFrontをマネジメントコンソールから1つずつ作っていました。当時のセットアップ手順書も、コンソールのクリック手順で書かれています。

動きはしますが、環境を作り直すたびに手順書を見ながらやり直すことになります。再現性も低く、設定の差分も残りません。

AWS CDKかAmplifyか。今回はAmplify Gen2にした

作り直しにあたって、AWS CDKとAmplifyのどちらにするか迷いました。このアプリはフロントが静的ファイル、バックエンドがLambda 1本とCognitoだけで、そこまでヘビーではありません。そこでAmplify Gen2で十分と判断しました。

構成は次のとおりです。

  • 認証:Cognito(Amplify Gen2のauth)
  • API:Lambda(Node.js / TypeScript)をAPI Gatewayの背後に配置
  • フロント:Amplifyホスティングで配信

Amplify Gen2はTypeScriptでバックエンドを定義します。細かい設定が必要な箇所は、CDKのコードで上書きできます。今回もCognitoのパスワードポリシーやトークン有効期限、API Gatewayの追加は、backend.tsの中でCDKのコンストラクトを使って書いています。つまり「CDKかAmplifyか」は二択ではなく、Amplifyの中でCDKも使える、というのが実際の感覚です。

// amplify/backend.ts(抜粋)
const backend = defineBackend({ auth, uploadToHarvest });

// Cognitoの設定をCDKで上書き
const cfnUserPoolClient = backend.auth.resources.cfnResources.cfnUserPoolClient;
cfnUserPoolClient.idTokenValidity = 60;
cfnUserPoolClient.tokenValidityUnits = { idToken: 'minutes', accessToken: 'minutes' };

画像が大きくて、Fluxの推論に時間がかかった

UG Hiroshima #10のハンズオンでは、アップロードした画像のサイズが大きく、SORACOM FluxのAI推論に時間がかかってしまいました。結果が返ってくるまで待たされる参加者が出て、ハンズオンがスムーズに進みませんでした。スマホで撮った写真は、そのままだと容量が大きくなりがちです。

そこで今回は、アップロード前にブラウザ側で画像を縮小するオプションを用意し、初期状態でONにしました。長辺を1280pxに収め、JPEG品質85%で出力します。すでに小さい画像は、そのまま送ります。

// frontend/script.js(抜粋)Canvas APIで縮小
const ratio = maxLongSide / longSide;
canvas.width = Math.round(width * ratio);
canvas.height = Math.round(height * ratio);
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
const dataUrl = canvas.toDataURL('image/jpeg', 0.85);

縮小の実装は、最初はLambda側でやっていました。ただLambdaにネイティブ依存のライブラリを載せると、ビルド環境の違いで面倒が出ます。そのため、最終的にブラウザのCanvas APIに移し、Lambdaからは依存を外しました。送信するデータ量も減るので、アップロード自体も速くなります。

アップロード先を選べるようにして、表記のズレも直した

もう一つの反省は、アップロード先まわりです。

  1. アップロード先のフォルダを指定できるようにした。 入力したパスはブラウザのlocalStorageに記憶します。
  2. 完了メッセージの表記を、Harvest Filesの画面と合わせた。 以前はメッセージにprivate/が付いていましたが、Harvest Filesのコンソールでは付きません。参加者が探したときに一致しないので、private/を外しました。

小さな修正ですが、ハンズオン中に「どこに入ったの?」と聞かれる回数が減ります。

イベント当日は、Kiro Crewにログを見させた

当日は、AmplifyにデプロイしたLambdaのCloudWatch Logsを、Kiro Crewのスケジュール機能で定期確認しました。2分ごとにスクリプトを走らせ、前回以降の新しいエラーだけを通知する形です。ログの時刻は日本時間に直して表示させました。

ログには個人を特定する情報を出していません。そのため「何人」ではなく「何回」しか数えられません。集計するときは、filter-log-eventsだとページングで取りこぼすため、CloudWatch Logs Insightsで数えるのが確実でした。

最終的には、スケジュール監視に頼り切るより、「直近のログはどう?」と聞いてその場で確認する使い方が中心になりました。

まとめ

UG Hiroshima #10の反省は、「手動構築」「画像が大きくて推論に時間がかかる」「表記と挙動のズレ」の3つでした。今回はAmplify Gen2でインフラをコード化し、ブラウザ側の画像縮小を初期ONにして、アップロード先の指定と表記も直しました。当日はログの確認をKiro Crewに任せました。


参考資料


この記事は tyamon(製造業の情シス)が実際に試した内容をもとに書いています。詳しくは運営者情報、ご質問はお問い合わせまで。

コメント

タイトルとURLをコピーしました