はじめに
こんにちは!ヤマダです。
最近AWS BuilderCardsをJAWS神戸のイベントで遊んだのですが、手持ちのAWSサービスカードを見て自分が構築するシステムを話すターンがあります。Lambdaは万能でほとんどのサービスとの連携ができるイメージですが、その他のサービスはどうでしょうか。連携できるかどうか、パッとは答えれない方も多いのではないでしょうか。自分も自信はありません![]()
そこで!今回はサービス同士の相性に詳しくなれるチャレンジを考えました!
その名も「AWSドミノチャレンジ」です。
AWSサービスをどれだけ連鎖させれるかを競うチャレンジです!
それではルール説明いってみましょう。
ルール
何も生み出さないシステムとはいえ、なんでもアリだと面白くないので4つのルールを決めました。
- ① 完全\$0.00ルール:100% 無料枠内。時間課金も取り込み課金も一切ナシ。「置いてるだけで課金」も「流したら課金」もダメ。
- ② 基本的にサービスは1回だけ:なんでもLambdaで繋ぐのはただのグルーコード。基本的には全部直結。
- ③ Step FunctionsのSDK統合は3サービスまで:使い切ったら外に吐き出す。同じサービスの使い回しは禁止。これは全員3サービス拾えちゃうけど、勉強になるのでOK。
-
④ 全部CDK:コンソールでポチポチはナシ。
cdk deploy一発で組み上がること。これはなんとなく。
特に①と②が効きます。「Lambdaを挟めば何でも繋がる」を封印すると、途端にどこが直結できてどこが詰まるのかを本気で考えることになります。
完成した装置の全体像
まず私が考えたAWSドミノの完成形をどうぞ。"Hello World" が位置情報をくっつけられたり、S3に保存されたり、感情分析されたり、音声化されては即捨てられ、翻訳されながら12サービスを旅します。
流れと繋ぎ方を表にするとこんな感じです。実際にデプロイして、端から端まで通ったのを確認済みです。
| # | サービス | 前段からの繋ぎ方 |
|---|---|---|
| 1 | Amazon API Gateway (REST API) | クライアントから POST /hello
|
| 2 | Amazon SQS | AWSサービス統合+VTLで SendMessage 直結 |
| 3 | AWS Lambda | SQSトリガー |
| 4 | Amazon S3 | Lambdaから PutObject(位置情報を付与) |
| 5 | Amazon EventBridge | S3のイベント通知(Object Created) |
| 6 | AWS Step Functions | EventBridgeルールで起動 |
| 6a | Amazon Comprehend | SDK統合 DetectSentiment
|
| 6b | Amazon Polly | SDK統合 SynthesizeSpeech(結果は捨てる) |
| 6c | Amazon Translate | SDK統合 TranslateText
|
| 7 | Amazon SNS | 最適化統合 sns:publish
|
| 8 | Amazon CloudWatch | SNSのメトリクスでアラーム発火 |
| 9 | AWS Systems Manager (OpsCenter) | アラームアクションで OpsItem 起票 |
初めて組んだとこもちょこちょこあり、勉強になります🎉
最初は15連鎖で作ろうとして諦めた話
正直に言うと、最初は15個繋ぐつもりでした。でもルールを守って「本当に直結できるか」「本当に\$0.00か」を一個ずつ検証したら、けっこう崩れました。この崩れる過程が一番勉強になったので共有します。
直接は繋がらなかったやつ
-
Transcribe が Step Functions の
.syncに非対応:Polly→Transcribe→Translate の「AI伝言ゲーム」をやりたかったのですが、Transcribeの文字起こしジョブ完了をLambdaなしで待つ手段がなく、泣く泣くTranscribeを外しました。 - EventBridge Pipes のソースにSNSが使えない:Pipesのソースは DynamoDB Streams / Kinesis / SQS / MQ / Kafka のみ。SNSは非対応で詰みました。
- DynamoDB Streams → AppSync はMutation必須:Streamsが直接Mutationを叩けないので、間にLambdaが要る。2個目のLambdaが必要になるので断念。
無料枠の有無
- Kinesis Data Streams:これ、リクエスト課金だと思い込んでたんですが、シャードの時間課金なんですよね。しかも無料枠外。つまり流さなくても置いてるだけで課金される(1シャードで月\$11くらい)。完全\$0.00ルールに真っ向から違反していました。
- Data Firehose:Kinesisの代わりに入れてみたものの、こっちも無料枠なし(取り込み量課金)。極小データなら実質\$0とはいえ「\$0.00」を看板にする以上、課金の芽は残せない → これも削除。
結局、データの受け渡しは Lambdaから S3 に直接 PutObject するだけにしました。S3なら容量もリクエストも無料枠内で、堂々の\$0.00です。こうして15 → 12サービスに落ち着きました。
見どころ解説
API Gateway → SQS を Lambdaなしで繋ぐ(REST API + VTL)
HTTP APIなら宣言的に一発なんですが、今回はX-Rayのトレース図に入口を出したくてあえてREST APIにしました(HTTP APIはX-Rayアクティブトレーシング非対応なので)。REST APIだとAWSサービス統合+VTLで自前変換します。
Action=SendMessage&MessageBody=$util.urlEncode($input.body)
捨てPollyと、デプロイして初めて分かったこと
Step FunctionsからPollyを呼んで音声化するんですが、この音声は誰にも聞かせず即破棄します。ところが最初 OutputFormat: 'mp3' にしてたら、実行時にこう怒られました。
Polly.InvalidContent: Failed to convert 'AudioStream' to string
Step FunctionsのSDK統合はレスポンスをJSONにしようとするので、Pollyが返すバイナリの音声ストリームを文字列化できずにコケるんですね。しかも cdk synth では気づけず、デプロイして叩いて初めて判明しました。「synthが通る=動く」じゃないという、いい教訓でした。
対処は OutputFormat: 'json'(Speech Marks)にしてバイナリを返させないこと。どのみち結果は捨てるので。。
締めは SNS → CloudWatch → SSM OpsItem
3アクション使い切ったらSNSに publish して外に吐き出し、SNSのメトリクスにアラームを張って、発火をトリガーにSystems ManagerのOpsItemを自動起票します。これが装置のゴールです。
ちなみに最初は「アラームでParameter Storeに書き込む」つもりでしたが、CloudWatchアラームのアクションにParameter Store書き込みは無いんですよね(SNS/EC2/AutoScaling/SSM OpsItem/SSM Incidentのみ)。というわけで同じSSMの中でOpsItemに変更しました。
おまけ:X-Rayが2つの島に分裂した
デプロイ後にX-Ray(ServiceLens)のトレース図を見たら、1本に繋がらず2つの島に分かれてました。
- 島A:Client → API Gateway → SQS → Lambda
- 島B:Step Functions → Comprehend / Polly / Translate / SNS
これはS3とEventBridgeがトレースコンテキストを引き継がないからで、疎結合構成だとこうなります。データはちゃんと流れてるので動作は問題なし(実機確認済み)。
この無駄から得られたもの
- AWS BuilderCards で無双できる:どのサービスが直結でき、どこでLambdaが要るかがわりと頭に入りました。
- アーキレビューでツッコめる:「その構成、間にLambda挟まないと繋がりませんよ」と言えるようになったかも。
- 無料枠に敏感になれる:時間課金と従量課金の違いで痛い目を見たので、いい感じに覚えました。
おまけコラム:もし月$1まで許したら?
今回は完全\$0.00が主役ですが、縛りを「月\$1以内」まで緩めると一気に自由になります。Kinesisを1シャード足したり、Firehoseを戻したり、Location Serviceで本物の位置情報を引いたり…。うまくやれば16連鎖くらいは見えてくる気がします。
「\$0.00部門(漢)」と「\$1部門(コスト最適化の戦略性)」で分けると、それぞれ別の面白さがありますね。$1部門は誰か挑戦してくれると嬉しいです。
おわりに
というわけで、1行の "Hello World" を返すためだけに12サービスを無駄に連鎖させて、しかも\$0.00で動かしきりました。作ってる最中はずっと「自分は休日に何をしているんだろう」と思っていましたが、終わってみればサービス連携の知識がゴリッと増えていて、無駄なようで無駄じゃなかったです![]()
今回私は12連鎖で疲れてしまいました。もし余裕で15連鎖いけるぜとかもっとこうしてはと思う方はAWSドミノチャレンジを実際にやってみてください!\$1部門は自分もまだ記録がないのでどれだけ上があるか検討もできません...!
ここまで読んでいただきありがとうございました!



