AWS Lambdaで画像版のWeb魚拓作成|Offers Tech Blog
あなたは誰?
こんにちは!Offers を運営している株式会社 overflow のバックエンドエンジニアの takkun7171 です。
いつの間にか 40 歳を超えてしまいましたが、Apex のソロダイヤを目指しつつ、エルデンリングやってます。
多分おじいちゃんになってもゲームやってますね。No Game, No Life です
これは何?
- Web 魚拓というサービスがありますが、その画像版のような挙動を目標にします。すなわち元画像が存在する場合はそちらを表示しつつ、S3 にキャッシュ作成。元画像がない場合で S3 にキャッシュがある場合はキャッシュ表示。元画像が存在せず、キャッシュもない場合は 404 という感じの参考実装[1]を AWS Lambda で簡単かつ汎用的に実現してみました。
- 悪意ある人に外部からたくさんアクセスされて、s3 に大量に画像が作成されないようにするため、簡単な認証をつけてあります。認証つけなくても参照はできるけど、保存は認証が必要という感じにしました
手順
-
まずは Lambda を作成します。慣れてるので Ruby で作成しやす。S3 の読み取り権限つけてください
-
こちらのリポジトリを clone 後
https://github.com/takundao71/lambda_fish_print_image
以下コマンドで upload.zip を作ってください。ソースコードは見ればわかるので見てください。説明はしません w 上で書いてある通りです。なお zip はコマンドにある通り、lambda_function.rb vendor が対象です。clone したフォルダ自体を zip すると階層おかしくなって、Lambda が動かなくなります。これで地味にハマりました。。このあたりの aws の UI、めっちゃわかりにくいです。。
rbenv local 2.7.2
bundle install --path vendor/bundle
zip -r upload.zip lambda_function.rb vendor
-
upload.zip をうp
-
続いて環境変数の設定
-
トリガーで API GATEWAY 追加します。レスポンスで画像返すので、バイナリーメディアタイプを*/*にしてください
なんとこれで完了なので、テストする
- rails コンソールなどで対象の画像 url を url エンコード
CGI.escape "https://upload.wikimedia.org/wikipedia/commons/c/c9/Moon.jpg"
- 認証のための digest 作成
digest_head_key = "head_key_dayo"
data = "#{digest_head_key}:#{Time.now.utc.strftime("%Y%m%d")}"
digest_hex = Digest::SHA1.hexdigest(data)
- エンドポイントにくくりつけてアクセス!(さっき作成した API Gateway のエンドポイントです)
{APIのエンドポイント}/default/fish_print_image?image_url=https%3A%2F%2Fupload.wikimedia.org%2Fwikipedia%2Fcommons%2Fc%2Fc9%2FMoon.jpg&d={上の認証digest}
- お月様の画像が表示されて、S3 に保存されてたら完了。やったね
-
編集注: 他者の著作物を対象とする場合、複製した画像を一般に公開すると公衆送信権や送信可能化権を害する恐れがあるため用途にはくれぐれもご注意ください。 ↩︎
副業転職の Offers 開発チームがお送りするテックブログです。【エンジニア積極採用中】カジュアル面談、副業からのトライアル etc 承っております💪 jobs.overflow.co.jp
Discussion