AWS

Lambda+S3+EC2を使用してできるだけ安くリアルタイムwebPエンコードをやってみる

S3にアップロードされる jpg画像をリアルタイムで webP にエンコードしたかったので 色々やってみた。   要件 S3 バケットには毎月1000万枚の2.2MB程度の jpg画像がアップロードされると仮定 これをアプリが引っ張る前にできるだけで速く webP にエンコードする必要性があります。 webP にエンコードする理由としては、画像の容量が小さくなることでユーザーのストレスを無くす、S3 にかかる料金を安くする、CloudFront の料金を安くするため。 ちなみに何でアプリでやらないかというと、iPhone で撮った生の画像を iPhone でエンコードを行うと、アプリがフリーズするぐらい結構重い処理だからです。致し方なし。   ① Lambda だけで全てやってみる S3 にアップロードをトリガーとして Lambda を起動して、Lambda でエンコードから S3 にアップロード、既存の jpg画像を削除を行うと、最小スペックで 22秒という脅威的な数値を叩き出します。 ちなみにメモリの使用量は 108/107MB 程度です。重いなあ… 全ての Lambda スペックで試し、一番安いスペックは 256MB でした。 これでも 11秒です。 256MB 枚数 秒数 課金 1枚辺り実行時間 無料枠 1秒辺り課金額 10000000 110000000 452.028 11 1600000 0.00000417 20000000 220000000 910.728 ちなみにひと月で 10000万枚を捌き切るにはこの Lambda 関数は並列で 42 個、必要になります。 $452 * 42 = 約210万… センキューAWS! これに CloudFront の料金も加算したらとんでもない額ですね。   ② エンコード用のサーバーを用意してみる not EC2 Lambda 関数を2つ用意し、Lambda – webP request(128MB) は Convert Server にある変換用サーバーにリクエストを送り、Convert Server がステータスコード 200 以外を返したときは、Lambda – webP encoder を呼ぶ係、Lambda – webP encoder は Convert Server  に代わってエンコードしてくれます。 Convert Server は Lambda の料金を節約するために、リクエストを受け取った瞬間に 200 を返すようにしています。サーバーにリクエストがくれば途中で天変地異や、タイミングよくサーバーが壊れる、リソース不足以外で、きちんと動作するようなコードであれば対策はできるであろうと思います。 この構成にしたところ、通常時(Lambda – webP encoderが呼ばれない)であれば、課金対象実行時間が 1,500ms となるので、Lambda だけだと { (1.5 * 10000000)…

S3をCloudFrontから配信&LambdaとWAFを組み合わせて利便性とセキュリティを確保してみる

この記事は、AWS Lambda Advent Calendar 2017 の5日目となります。 今回は S3 にある画像ファイルを CloudFront から配信をしつつ、 CloudFront のアクセスログを Lambda で解析を行って、WAF の IPリストへ追加を行って、セキュリティの担保を行ってみようと思います。   S3 を CloudFront から配信する理由 前提条件に、弊社の S3 バケットにはユーザー個人が撮影した画像がアップロードされます。 なのでセキュリティには気を置いてしっかり運用していく必要性があります。 AWS SDK を使用すれば S3 から署名付きURLが吐き出され、これにアクセスすれば画像を取得できます。が、この署名付きURLには有効期限が設定されており、アプリから使うにはちょっと面倒です。 S3 を CloudFront から配信をすると、WAF が使えるようになるので固定URLで配信しつつ、セキュリティも担保できます。   構成 ①ユーザーが CloudFront にアクセスを行う ②リクエストヘッダー等を WAF へ送る ③WAF にあるルールと照合し、結果を返す ④③がOKなら S3 から画像を持ってくる(NG なら 403 を返す) ⑤アクセスログを S3 へ保存する ⑥⑤のタイミングで、Lambda が発火する ⑦アクセスログに HTTPステータスコードが 200 以外のものがあったら、IPを WAF の IPリストに追加する Lambda 関連のアドベントカレンダーなのに、Lambda の部分を特筆するところがねぇ…   CloudFront ディストリビューションの作成 オリジンに、対象の S3 バケットを。 ログの設定も何となく分かると思います。 S3 は CloudFront からのみアクセスできるようにしておきます。 ブルートフォースアタック等で、キー(/user_id/hoge_id/file_name_.jpg みたいな)がバレないように、こうします。CloudFront + WAF を組み合わせればキーがバレる前にブラックリストに入れて、アクセスを拒否できます。   WAF web ACL の作成 AWS resource to associate には先程作成した CloudFront のディストリビューションを設定します。 ルールの作成部分では IP address で作成する。 文字列判定を使えば特定の文字列をヘッダーに載せるとアクセスできるなんて仕組みもできます。   こんな感じです。 最初に IPアドレス判定を行ってから、文字列判定のルールでヘッダー認証をします。順番が大事です。今回はなんちゃってヘッダー認証があるので、デフォルトアクションは全て 403 を返すようにしています。   Lambda スクリプトを作る 言語は好きなものを選んでください。 今回僕が書いて運用しているコードを貼っておきます。 IP_SET_ID には WAF -> IP addresses の自分で作成した空のルールにアクセスすると、URLにある /ipsets/<ここ> を指定します。…

Vultr.com $5 VPS と AWS EC2 t2.micro どっちがオススメか

初めて精神安定剤みたいのを買いました。 今後外出するときは使用してみたいと思います。   背景 会社のHPなどサービスを提供する際に停止してもそこまでクリティカルでないものを 如何に安く運用するかと考えたときにVPSかEC2かで悩んだので色んな観点からまとめようと思った次第です。   EC2以外の選択肢 EC2は思ったほど性能が良くない(と耳にしたことがある)ので クリティカルじゃないものなら敢えてEC2じゃなくて他社のVPSで良いのではと思う 国内のVPSだと さくらインターネット GMO カゴヤ ConoHa 国外だと Vultr.com cloudatcost AlphaRacks とか色々あります。 この中でもVultr.comは安くて安定性も良かったので 今回は Vultr.com $5/m のVPSとEC t2.microを比べてみます。 スペックはどちらも 1Core / 1G です。 月額$2.5で東京リージョンがある激安SSD VPSを契約してWordPressを移行した「Vultr」   スペック EC2 t2.micro Vultr  $5 CPU Intel(R) Xeon(R) CPU E5-2676 v3 @ 2.40GHz Virtual CPU MEM 1G 1G SSD 8GB (gp2 – EBS) 25GB OS CentOS 7.3.1611 CentOS 7.3.1611 参考 ap-northeast-1a 東京リージョン どちらも CPU/MEM は 1Core/1G です   UnixBench t2.micro – 1回目 [crayon-5b4efed512b36706970209/]   t2.micro – 2回目 [crayon-5b4efed512b42759982618/]   Vultr $5 – 1回目 [crayon-5b4efed512b46970243139/]   Vultr $5 – 2回目 [crayon-5b4efed512b49335379264/]   結果 – UnixBench EC2 t2.micro Vultr $5 1回目 1586.7 1303.6 2回目 871.6 1333.7 1回目は t2.micro が優勢だったけどこれはT2インスタンス特有のバーストです。 クレジット残高が無くなったので2回目は本来の性能(言い方が難しい)になってます UnixBenchって何だかんだCPU寄りの結果だと思ってる(個人的に)ので fioもやってみたいと思います。     fio $ fio -filename=/tmp/test2g -direct=1 -rw=…

Ansibleのs3モジュールを使ってディレクトリごとアップロードする

梅雨の季節がやって参りました。 Ansibleのs3モジュールを使ってディレクトリごとアップロードする方法を覚え書きとして。   認証情報を環境変数に入れておく Ansibleで使うAWSの認証情報はPlaybookに書き込むか 環境変数を使うかで選べます。 万が一のことを考えて環境変数で管理したほうが良いと思います。 [crayon-5b4efed512d86517654020/]   ファイルのアップロード [crayon-5b4efed512d93031395888/]   ディレクトリごとアップロード(Ansible 2.3以降) [crayon-5b4efed512d95156134450/] key_prefixがないとバケット直下にファイルが展開されちゃうので key_prefixを設定しておきます。 こうすると BUCKET_NAME/source/<sourcecodeの中身> ってなる。   boto required for this module Ansibleを実行するホストでAWSの操作をする場合、 botoとかいうPythonのモジュールをインストールします。 加えてdelegate_to: 127.0.0.1をタスクに追加しないとリモート先で実行されてしまって エラーが消えないのでご注意を。 逆にリモート先で行うならリモート先で実行します。 [crayon-5b4efed512d98005476881/]   それでも解決できない場合 引数にansible_python_interpreterをつけて実行する ansible-playbook -i production/hosts api.yml --extra-vars "ansible_python_interpreter=`(which python)" --user root --ask-pass hostsファイルにansible_python_interpreterをつける [crayon-5b4efed512d9b403066630/]  

no image

Amazon CloudFront CDN を使用して WordPress を使ってみる

CDN をどれ使おうかと色々試してみる中で勉強がてらAmazon CloudFrontのCDNとWordpressを組み合わせて使ってみることにした。   CDNの種類 [table "19" not found /]     CloudFront CDN Amazon AWSのCDN、従量課金制で別ドメイン型である。 リクエスト数だけで見ると料金は安いがページの容量が大きかったりすると一気に料金が跳ね上がる。 画像の容量を抑え、CSSなどはインライン化とかしてリクエスト数を減らせば料金も抑えられると思う。 HTTPSで運用しているサイトは、HTTPSで配信する必要性がある。     CloudFrontの設定 証明書のアップロード 初めてCloudFrontを使ったわけですが証明書のアップロードが面倒くさいです。 Web上からできないのでコマンドラインから証明書をアップデートする必要性があります。 参考 http://qiita.com/n0bisuke/items/a2a7d5efdc1311dc479a なおCDN用に証明書を用意できないので今回はデフォルトの証明書を使います。   CloudFrontの設定 イメージ図的にはこんな感じであってるのだと思う。draw.io 便利〜 HTTPSでサーバーを動かしてるときには 同じくHTTPSでCDNから転送しないと主要ブラウザではエラーを吐いてレイアウトが崩れて表示されてしまいます。   General Default CloudFront Certificate (*.cloudfront.net) にチェックをつけます。 独自ドメインでCDN配信するにはまた工程が増えるのでこのまま使うことをオススメします。   Origins Originの設定です。 今回はHTTPSでしか配信を行わないので Origin Protocol Policy は HTTPS Only にします。   Behaviors 特に記述することもなく。   ログイン画面、管理画面でキャッシュさせないように上記のような設定をします。 Path Patternに関して私の環境では /wordpress を付けてます。     Behavioursの設定は上記のようになると思います。   WordPressの設定 WordPressアドレス(URL) : https://<CloudFrontから割り当てられたアドレス>/wordpress サイトアドレス : https://luispc.com とします。   これで画像を開いてみるとCloudFrontアドレスになっていると思います。

Amazon Web Services(AWS)から6,000円引き落としされた話

ファンクラブイベントのチケット代入金が明日までなので今日決済しようと思ったら 口座に4,000円しかなかったんです。