Ponz Dev Log

ゆるくてマイペースな開発日記

Google Cloud Certified Professional Cloud Developer認定を取得しました

10月にタイトル通り認定に合格したので、振り返りです。 あまりProfessional Cloud Developer認定のことを書いている記事はググっても少ない気がするので、覚えているうちに書いておきます。 (Googleの認定なのにググっても情報が少ないとは...)

ちなみに今年の1月にもProfessional Data Engineer認定を取得してます。 そちらの記事もよければどうぞ。

ponzmild.hatenablog.com

どんな試験か?

公式サイトによると、Professional Cloud Developer認定をとると以下の能力を持つことを証明できます。

  1. フルマネージド サービスを利用する Google の各種ツールを使用して、Google の推奨する方法を実践しながら、スケーラブルで可用性の高いアプリケーションを構築します。
  2. また、次世代データベース、ランタイム環境、デベロッパー ツールを利用した経験もあります。
  3. 少なくとも 1 つの汎用プログラミング言語に精通しています。
  4. さらに、Stackdriver を使用するスキルがあり、コードのデバッグやトレースを行うための有意義な指標やログを生成できます。

cloud.google.com

ちなみに認定を取得すると証明書が発行されます。この証明書はCredential Holder Directoryというサイトで取得した人として全世界に自慢することができます。各国や資格ごとにどんな人が認定を取得しているのか見れるので面白いです。

また、取得すると認定ロゴ入りのパーカーやカバンを購入できるバウチャーコードも貰えます。(本当に貰っている人がいるのか謎でしたが、以前参加したイベントでロゴ入りカバンを持っている方がいました)

何を問われたか?

出題形式

制限時間2時間で全て四択問題です。ユースケースに沿って最適なプロダクト・ソリューション・実装方法を選択する問題が出題されます。

Data Engineerと比較すると、ユースケースのシチュエーションが具体的かつ踏み込んだ内容に感じられました。 また、試験ガイドに掲載されているケーススタディを題材にした問題が(体感で)3割程度とData Engineer認定試験よりも多めでした。

出題内容

試験ガイドに掲載されているように、以下の5つのトピックを織り交ぜた設問が出題されます。

  1. スケーラビリティ、可用性、信頼性に優れたクラウド ネイティブ アプリケーションの設計
  2. アプリケーションのビルドとテスト
  3. アプリケーションのデプロイ
  4. Google Cloud Platform サービスの統合
  5. アプリケーション パフォーマンス モニタリングの管理

例えば以下のような設問が出題されました。(あくまで例です)

(例1)

Google Compute Engineにのせたアプリケーションを公開するためにXXXX(gloudコマンドいくつか)の設定を以下のように行いました。しかし、インスタンスグループのヘルスチェックが通らず再起動を繰り返します。各インスタンスへのSSH接続が可能なことは確認済みです。この状況の原因と対応策を選択してください。

(例2)

あなたは同僚からCloud Datastoreからデータを取得するコードのレビューを依頼されました。以下のコード(JavaPython)を確認してあなたがすべき助言はどれですか。

かなり具体的な設問ですね。逆にどのサービスが適切か選択させる問題はベストプラクティスさえ押さえておけば瞬殺できます。

認定を取得に向けた学習

ここからは事前に何を学習したか書き連ねます。期間的には約3ヶ月くらい見ておくと良いです。 基本的には他のProfessionalレベルの試験に合格していれば基本知識を流用できます。

  • Coursera
    • 認定をとるために必要な知識と実装レベルの取得は以下のコース(4つのサブモジュール)をやりました。
    • 私が受講した時は英語版しかなかったのですが、ここ1~2ヶ月でGCPのコースは日本語版が増えているので、これから受講される方は日本語版のコースの選択をお勧めします。
    • Data Engineerと被る領域が多いので、他の認定をお持ちの方はqwicklabだけでも良いです。

www.coursera.org

  • qwicklab
    • ハンズオン形式の学習サイト。
    • 1テーマでも複数のトピックをまとめて学べる"Quest"をやると良いです(全てのQuestをこなすには¥3,00~¥4,000くらいかかりますが)。
    • 自分は雰囲気でしか知らなかったStackdriverのQuestを一通りやりました。

www.qwiklabs.com

  • 模擬試験を受験する
    • Google Forms形式で提供された無料の模擬試験を何度も受験することができます。
    • 分からないことがなくなるまで解きます。
    • 模擬試験の各問題は、例え正解していても「なぜ他の選択肢が誤りなのか」説明できるようになるまで調べると自信を持てます。

cloud.google.com

  • 実際にGCPで手を動かす
    • Data Engineer認定を取得した時と同様に、GCPの各サービスの知識はドキュメントと合わせて手を動かた時が一番身につきました。
    • ここで重要な点として、 手が止まったら最初に読むべきは公式ドキュメントです。 マネージドサービスは結構な頻度でアップデートされるため、非推奨の機能を使わないようにするためにも公式ドキュメントを第1のリファレンスにすることをお勧めします。
    • あとはひたすら手を動かしましょう!某メンターの言葉を借りるならば、"Just Do It!!" ですよ!

次はProfessional ArchitectもしくはNetwork Engineerを取りたいですね。

以上。

Kubernetes完全ガイド 読了後感想

Kubernetes完全ガイド』を読んだので感想の投稿です。 先月の技術書典7でKubernetes関連の本を読んでKubernetes強者になりたい欲高まったので読んでみました。

book.impress.co.jp

ターゲット読者は誰か?

Kubernetesを利用する可能性のある方全てが対象となっています。 Kubernetesを何も知らない人は頭から中盤くらいまで読めば基本的なことは全部できそうです。(Dockerの説明は章が設けられているものの事前に押さえておいた方が良さそうですが...)

また、普段からKubernetesを使っている人でも復習と新しい発見ができる本です。リファレンス用途としても良さそうですね。

どんな本か?

この本の『はじめに』で記載されているように、 Kubernetes上のアプリケーション開発で利用する可能性のあることを網羅的に解説されています。

内容としては前半〜中盤過ぎまでは、Kubernetesそのものの解説と、アプリケーション開発者が押さえておくべきリソースの解説がメインです。 リソースも5つのグループに分けて体系的に説明されており、リファレンスとして後で読んでも分かりやすい構成になっています。

また、後半からはKubernetesのリソースの他にもアプリケーション開発で忘れてはならない セキュリティやモニタリング、ロギング、CICD、サービスメッシュといったトピックにも触れられています。

ピックアップ

個人的にこの本のすごいなと思った点を2つピックアップします。

体系的にリソースが解説されている

各リソースを関係性を理解した上で丁寧に解説されています。

もちろん1つ1つのリソースの説明はQiitaやブログ記事をググればなんとなく理解することは可能です。 ですが、例えば以下のようなリソース違いやkubectlコマンドの意味、リソースの必要性を説明せよと言われると途端に難しく感じられます。

  • DeploymentとReplicaset
  • PersistenceVolumeとPersistenceVolumeClaim
  • ConfigMapとSecret
  • Podのrequestとlimits
  • ClusterRoleとClusterRoleBinding

上記のリソースは触れる機会が多いのにも関わらず意味を理解し切れていない、いわゆる『雰囲気』で触りがちです。 2つずつリソースを並べましたが、これらの違いやkubectlのコマンドの意味を説明できなかったら断片的でも読む価値があります。

隠れた標準機能を発見できる

また私は初見でしたがKubernetesの標準機能でここまでできるのかと目に鱗な機能を知ることができます。 一例として以下のようなリソースの解説がされていました。

  • リソースに制約を設けるリソース (ResourceQuota, LimitRange, PodPreset)
  • セキュリティに関するリソース (PodSecurityPolicy)
  • ネットワークに関するリソース (NetworkPolicy)
  • 外部サービス(AWSGCP)を作成・管理するリソース (ClusterServiceBroker, ClusterServiceClass, ClusterServicePlan)

上記の機能は、アプリ開発者よりもKubernetesクラスタを運用を担当する方やシステム全体をマネージするSREの方々が意識することが多いかもしれません。 それでも自前で実装したり難しいツールを入れなくともKubernetesが標準的に提供している機能でリソース制約や外部サービスのプロビジョニングまでできるのは驚きです。

この本が執筆されたのはKubernetes v1.11なので、最新版(1.16)だともっと増えているかもしれません。。。

総評

読んでみて改めてKubernetesの奥深さを理解できました。まさに完全ガイドとの名前の通りの書籍です。

私は業務でもKubernetesを使っていますが、 今まで知らなかったことや雰囲気で分かったつもりになっていたことをキャッチアップすることができたので超絶推せる本です。 (弊社の同僚にもオススメしておきました。)

この書籍で扱われていないこともまだまだあるとの情報を得ましたので、深掘りしていくのが楽しみです。


せっかく本を一読したのでステップアップのために 2019年度内にCKAD取得を目指します。 さて、頑張るぞ。

www.cncf.io

技術書典7 参加レポート ~アウトプットは出す方も見る方も楽しい~

9/22開催の技術書典7に出展者として参加してきました。今回はサークル参加者として、また1人のイベント参加者としての振り返り記事です。

実は技術書典には初参加でもあります。ツイッターで盛り上がっているのを見て、これは自分もやってみていいんじゃないかと勢いで申し込みました。

勢いで申し込んだものの、結果としては参加者で行くよりも収穫があったと感じます。

どんな本出したの?

分散システム間のメッセージングのためのOSSである、NATSの本です。 NATSはシンプルかつスケーラブル、ハイパフォーマンスなメッセージをPub/Subパターンでやりとりするためのプロダクトです。 Boothで電子版書籍版を出しているので、ご興味ある方は是非読んでいただければと。

ponzdou.booth.pm

この本を出すためにNATSを理解しようと悪戦苦闘しましたが、苦痛ではなかったです。
Slackグループに参加してリアルタイムで動向を追ったり、GitHubソースコードを読み解いたり、 最後には自分でクライアントアプリ作ったりしてました。
NATSへの理解がだいぶ深まった自信があります。

売り上げ結果

リアルな数字としてどんなものか参考までにお見せします。

  • 最終被チェック数: 106
  • 印刷: 物理本80部 + DLカード150枚
  • 売上: 物理本57冊 + DLカード58枚 (基本は物理本とセットだが、単品販売が1枚あった)
  • 現金: 簡単後払い = 27 : 31

新刊の進捗や入稿といった様々なタイミングでTwitterで宣伝したおかげか、被チェック数は初参加ながらいい伸びでした。

支払い形態に関しては、予想よりは現金払いが少なかったです。 イベント2日前に公開されたiOS13で技術書典アプリが動かない事象があったので、もっと現金払いが多いかなと想定してました。 (私は当日はiOS12が入ってるiPadを持って行きました)

上記以外にもBoothでも数点購入されている方もいらっしゃたので、実質的には計60冊以上売れたことになります。

これだけ多くの方に興味を持っていただけたことに感謝いたします。 購入していただいた皆様、また購入せずともスペースまでお立ち寄り頂いた皆様、本当にありがとうございます。 在庫は次回のイベントに参加した時に持ち込む予定です。

当日の様子

まず最初に感じたのは、 ワンオペは無理ですね!!!!(確信)
後輩が売り子として1人ヘルプ(しかもコミケで何度か売り子経験あり)してくれたことが大きくプラスに働いて、 慌てず落ち着いてオペレーション回せました。後輩が来なければ本を買いに行く余裕はなかったと思います。

本を頒布している間は予想以上に割と話しかけてくださる方が多かったです。
商業誌を書かれている方もスペースに来ていただいたのでビックリしましたが、 お話しできた上に新刊を買っていただいたのでめちゃくちゃ嬉しかったです。

それにお隣のスペースの方(Prometheus本の方)ともお話しもできましたし、 実は今回の新刊の中でNATSをPrometheusで監視しようという章があったのでそれで話が盛り上がりました。 (もちろん両隣のスペースの新刊は紙本買いましたよ)

反省点

ここまでは良かったことを書き連ねましたが、反省点もいくつかありました。

当日にブースでいくつか質問をいただいたのですが、自分の中で整理しきれていないことがいくつもありました。
事例と比較という割と基本的なことが疎かになっていました。

印象に残っている質問は以下4つですね。これらは整理してブログでアウトプットしようと思います。

  1. NATSとMQTTの違いは? (Kafkaとの違いを聞かれるかと全くなかった)
  2. ぶっちゃけAmazon SNSとSQS使えばよくない?
  3. NATSは他のメッセージングプロダクトを置き換え得る?
  4. NATSを使った事例ある? (Cloud FoundryとNGS以外は?)

イベント参加者として

サークル参加者ではなく、1人のイベント参加者としての感想。

他のサークルスペースの本も楽しみにしていたので、買いあさりました。 興味のあるもの、技術的性癖に刺さるものばかりで、Boothで買ったものを合わせて全26冊購入です!

どのブースのどの本を買ったか並べてみましたが、この記事を買いている途中で買い忘れた本を思い出したのでまた増えるかも笑

ちなみに私が買った本は全て簡単後払いかBooth購入可能でした。
技術書典アプリは結構使いやすかったですし、当日大きい財布も持たなくて良かったのは助かりましたね。
(コミケだと硬貨とお札を大量に用意しないといけないので、コミケに比べれば気楽)


技術書典7は総じて楽しい時間でした! 別の技術書イベントにも出展したいですね。

今回のNATS本をNATS Streamingも含めてパワーアップさせたいですし、KafkaとMQTTとの比較本もいいですね。
最近はサービスメッシュ周り(Istio, Envoy, Gloo, Openshift Service Mesh)も気になってます。 アプリよりも少し下のレイヤーに興味が出てきているので、ネタを集めて温めておきます。

最後にこの本をレビューいただいた @hiroga_cc さん、読者目線でのレビューいただき本当にありがとうございます。

以上。

Pythonによる新しいデータ分析の教科書 読了後感想

今回は自分にしては珍しいPythonの読書記事です。

データ分析と機械学習を使った予測モデル構築のお仕事をすることになり、 基礎練習として翔泳社から出版されている『Pythonによる新しいデータ分析の教科書』を読んだのでその感想になります。

Pythonによるあたらしいデータ分析の教科書 (AI&TECHNOLOGY)

Pythonによるあたらしいデータ分析の教科書 (AI&TECHNOLOGY)

ターゲット読者は誰か

この本でターゲットにしているのは、主に以下2点が当てはまる エンジニア です。

  • Pythonをある程度理解している
  • データ分析・予測モデルの作成を行いたい初学者〜中級者

「プログラミングは全くできないけど、Pythonを使えば簡単にできるかも」と安易に考えている方には向いていないです。 実行環境としてJupyter Notebookを使いながら、Pythonでガッツリとコーディングします。

何が書かれていたか

これからデータ分析・機械学習を行うエンジニアに向けて、以下4つのテーマが書かれています。

  1. エンジニアが求められている役割
  2. 分析に使う数学の基本
  3. ライブラリを使った分析・可視化・予測モデル構築
  4. データ収集と、自然言語・画像処理のためのデータ加工

内容的には学術的な部分には深入りせずに、機械学習を使った分析の各ステップに重点を置いています。 そのため、実務的にエンジニアが使うライブラリ・前処理・モデルの知識にページ数が割かれていて、Python機械学習そのものの説明はサラッと流しています。

また、機械学習の処理の手順に沿って、データの加工→可視化→モデルの構築→評価の順に章立てされているため それぞれでどのような処理が必要になるのか、手が掛かる部分はどこか、クラウドサービスを使いながらできるところはどこかと想像しながら学べます。大きな流れの中の立ち位置が明確なので、闇雲に手を動かしているという感じがしません。これはいいぞ!

章立てとともにこの本で重要なのが機械学習の手順として以下の図です。 本書10ページに掲載されているこの図は紹介されているライブラリ以外でも共通して覚えておくべきものです。

f:id:accelerk:20190813234632p:plain
機械学習の処理の手順

クラウドベンダーの提供するサービスを使うと多くの手順が省略・簡略化される傾向にありますが、自分が今どの処理に手をつけているのか、次はどの処理に進むのかを理解する助けになりますね。 機械学習の記事や用語を調べるとそれぞれのステップが個別に紹介されることが多いので、この図を見てようやく全体像を掴むことができました。

ライブラリの章では以下のものが紹介されています。どれも分析時に頻出するライブラリです。

  • データ加工
    • NumPy
    • Pandas(データ加工)
  • データ可視化
    • Matplotlib
  • モデル構築と評価
    • scikit-learn

それぞれ手を動かしながら学べるところも、理解しやすいポイントです。1章の中でそれぞれ30~40ページほどの内容なのでとっつきやすいです。 データもアヤメの有名なデータセット(Iris dataset)を使って進めていたので、個人的には楽しかった。

さらに、ここで作成したモデルはpickle形式やjoblib形式でエクスポートすればクラウドベンダーのサービスで利用することもできます。 GCPだとAI Platformでscikit-learnのモデルをトレーニング・デプロイできるので、クラウド機械学習を一緒に使う方法を学ぶこともできますね。

cloud.google.com

総じて読みやすい。全体像から詳細を順序立てて進めて理解できる良書だったと感じました。

参考

機械学習そのものの説明はサラッと流されているので、GoogleがUdemyで配信している『はじめてのAI』を視聴することをオススメします。

https://www.udemy.com/google-jp-ai/

自分自身は予測モデル構築や機械学習には一切興味が出なかった人だったので、実務的にはどんなケースがあるのか、エンジニアとしてどのように解決するのかを学ぶのには良い入り口だったと思います。

メッセージング基盤のNATSを超ざっくり解説する

システム間を疎結合に保ちつつ非同期で通信しようとすると、必然的にメッセージング基盤が必要になります。

もしメッセージング基盤を手っ取り早く使うのであれば、クラウドベンダーのサービス、例えばAmazon SNSGoogle Cloud Pub/Subを使うのが一番です。(自分で環境を立てなくて済むならその方法を選択した方がいいというのが自論です)

ただし、手元に環境を用意したり接続用のロールやサービスアカウントを作るのは面倒です。

OSSはどうでしょうか?メッセージングやストリーミング処理のデファクトスタンダードとなっているKafkaという素晴らしいプロダクトがあります。

ただし、耐障害性もありスケーラビリティを実現するためにZookeeperの複雑性を受け入れなければいけないので、これまた面倒臭いです。(もちろん、Amazon MSKやConfluent Cloudのようなマネージドサービスを使う手もあります)

aws.amazon.com

では、もっと簡単にPub/Subスタイルのメッセージングを自前で用意できないのかと探して見つけたのがNATSでした。

nats.io

詳しいところは技術書典7に出す同人誌で書こうと思いますが、 NATSは何が特徴で何が他よりもすごいのか、頭の整理のためにもブログ記事として書き記しておきます。

Subject-based messaging

メッセージのやりとりは全てSubjectを通じて行います。

KafkaやAmazon SNSのようなPub/Sub型のメッセージングに慣れた方はメッセージの購読にTopicやSubscriptionを作成したでしょう。 驚くことにNATSには TopicやSubscriptionがありません 。PublisherとSubscriberの間に立つ登場人物は Subjectただ1つです

PublisherはSubjectを指定してメッセージを配信し、同じSubjectを購読しているSubscriberにNATSがメッセージをルーティングしてくれるのです。 「NATSは(メッセージ)キューではなくルータ」であると主張している方もいます。

Flexible Subject

全てのメッセージのやりとりはSubjectを通じて行うと書きましたが、配信先は1つに限定されません。 Subjectにはワイルドカードを使えます。

ワイルドカードにも2種類あり、特定の1階層のみ全てのメッセージを受け取る * (アスタリスク)と、特定の階層以下全て階層向けのメッセージを受け取る > (不等号) があります。

例えば、time.* というSubjectを購読するSubscriberは、Publisherが time.ustime.jp に向けて配信したメッセージのどちらからも受け取れます。ただし、time.jp.tokyo のようなさらに下の階層までSubjectが指定されてメッセージが配信され場合はSubscriberはメッセージを受け取れません。 time.> というもう1つのワイルドカードを使ったSubjectならば受け取ることができます。

Kafkaに慣れた方ならば、1Topicに対して複数のSubscriptionがぶら下がり、これらのSubscription全てをSubscribeしている状態をイメージしていただくと良いです。

3style messaging

メッセージングのスタイルにも3種類あります。

  • Pub/Sub
  • Request/Reply
  • Queue Group

Pub/Subを拡張してメッセージの返信(Request/Reply)もできることが特徴です。 AWSだと最近Temporary Queueというものができましたが、やっていることはこれと近いですね。

aws.amazon.com

また、Queue Groupのようなロードバランサーの仕組みがあるのも特徴ですね。

Zero Configuration

設定なしにメッセージングを始められるのも特徴です。 例えば以下のようなことを実現するのに設定は全く不要です。サーバーやクライアントを構成したら自動的に設定されます。

  • Subjectにメッセージを配信するための設定
  • Subjectをからメッセージを購読するための設定
  • SubjectからSubscriberへのメッセージ配信のロードバランシングの設定
  • 災害対策のためのNATSサーバークラスタ冗長化

Simple Client

クライアントも実装が楽チンです。クライアントライブラリ自体が30以上の言語の実装があり、インターフェイスもシンプルであるためです。 Node.jsのクライアントライブラリである nats.js を例にとると、以下のようにしてメッセージの配信・購読が可能になります。

github.com

Pub/Sub messaging with NATS

全てのメッセージがSubjectを通じてやりとりされるため、クライアント側も実装が簡単です。見た目もスッキリしていますね。

Deliver AT MOST ONCE

NATSはメッセージを1回しか配信しません。(At Most Once戦略)

これはディスクやDBのような2次ストレージにメッセージを保存していないためです。 裏を返すとメッセージを管理する手間が省けるのでシンプルではあると言えます。(物は言いようですね) この特性のため、受け取りに失敗した or 購読する前に配信されたメッセージを再送する手段がありません。

その一方でKafkaは稼働しているマシンのディスクにメッセージを書き込んでいるため、始点を指定してメッセージを再送できます。

また、ストリーミング処理のための拡張実装であるNATS StreamingやLiftbridgeはこの問題を解決して最低1回(At least once)配信できるようになります。

github.com

www.infoq.com


もう少し深掘りしたことや本番運用に向けたNATSのクラスタリング・認証認可の話は技術書典7で出す本をお楽しみに!!

AWSによるサーバーレスアーキテクチャ 読了後感想

サーバーレスアーキテクチャのまとまった書籍ないかなと探して見つけた一冊を読んでみたので、感想を含めてメモ書きです。

AWSによるサーバーレスアーキテクチャ

AWSによるサーバーレスアーキテクチャ

TL;DR

Youtubeクローンのサービス作成を通して、サーバーレスアーキテクチャでサービスを作るためのアーキテクチャ、考え方、コンポーネントの使い方と実装・テストといった設計からサービスの公開までの一連の要素を学べます。

特にアーキテクチャの原則や各章で説明されているコンポーネントの組み合わせ・実装はAWSに限らず汎用的に適用できるものだと手を動かしながら感じました。 それと個人的にはちゃんとテストを書こうって書いてあったのは好印象。

また、サーバーレスのコンポーネントとしてAWSのサービスを多用していますが、類似したサービスは他のクラウドベンダーやOSSにも存在するので置き換えて作ることもできそうです。

以下、この書籍からピックアップして所感を書き連ねます。

サーバーレスアーキテクチャの原則

この書籍で一貫して適用される原則です。具体的には以下の5つになります。

  1. オンデマンドでコードを実行するために、サーバーを自分で立てるのではなくコンピューティングサービスを使う
  2. 目的が1つでステートレスな関数を作る
  3. プッシュベースのイベント駆動パイプラインを設計する
  4. より厚く強力なフロントエンドを作る
  5. サードパーティサービスの活用する

1つのアプリケーションサーバーで実現していたことをサーバーレスアーキテクチャで実装するにはどれも重要な原則です。

(2)を突き詰めると(4)や(5)も自然と実施するようになるので、それぞれ独立した原則ではなく相互関係があるように思えます。

(3)のイベント駆動パイプラインはAPI Gatewayから接続されるようなサービスではなく、非同期サービス側だけで使うアーキテクチャ・実装に見えます。ですが、背後にこのようなアーキテクチャのパイプラインがあることを意識すると、同期的に処理するAPIインターフェイスや、APIとパイプラインの接続部分の実装が変わります。

サーバーレスのコンポーネント

この書籍で使用したコンポーネントは以下の通りです。

  • AWS Lambda ... Computing Service
  • Amazon S3 ... Storage and Event
  • Auth0 ... OAuth style authentication
  • Amazon SNS ... Notification
  • Amazon SES ... Email
  • Amazon CloudWatch ... Monitoring
  • Amazon CloudTrail ... Auditing
  • Amazon API Gateway ... Relate API with Lambda
  • Firebase Realtime Database ... Realtime datastore
  • AWS Step Functions ... State machine

こうやって使ったコンポーネントを見ると、サービスをたくさん使いました。 下の参考記事みたいにサーバーレスのサービスのアーキテクチャServiceful Serverlessと表現するのは的を得ていますね。

--> サーバーレスによる大変革

標準的だったり汎用的な機能はクラウドベンダーもしくはサードパーティーのサービスを使い、カスタムコードは単一の目的に特化した最低限だけ書く。そしてそのカスタムコードはサービスを繋ぐ(=グルーコードにする)。カスタムコードをいかに書かずに実現させるかを考えるのはゴリゴリコードを書くのとはまた違った楽しさがあって良いです。

Good Point

  • 実際にコードを書きながら学べる

    • これは言わずもがなですが、ただ読んでいるだけではなく手を動かしながらの方が理解できますね。
  • 自然とクラウドネイティブなサービスを作れる

    • まるでCNCFの定義のようなクラウドネイティブなアーキテクチャに結果的になっています。「管理しやすい」については疑問が残りますが、他の要素については概ね満たしていますね。
    • スケーラブルなサービスである
      • Lambdaやイベント駆動パイプラインを使用することで、特定部分がボトルネックにならない!
    • コンポーネントが互いに疎結合となっている
    • 耐障害性がある
      • 特定の部分が失敗したり応答不能になっても、他のサービスには影響しない。
    • 可観測性が高い
      • CloudWatch Metrics/LogsやCloudTrailを使うことでそれぞれのコンポーネントの状態を把握できるようになっている。
  • 上記の原則に沿って、サーバーを意識しない/自分で管理せずサービスをどのように作るのか明確であった。

    • 自分でEC2やベアメタルサーバーを立てずにLambdaを使う、フロントエンドを厚くする、サードパーティーサービスを活用して自分でコードを書かずに機能を実現できるといった具合です。
  • エラーハンドリングについてアーキテクチャ的解答があった。

    • 単純に実装としてDLQを使いましょうで済ませてないです。なんでDLQを使わないといけないんだっけ?の理由が自分の中ではフワッとした理解に留まっていたので、この解答には膝を打った。
      • (Why) マイクロサービスになるにつれて全てのサービスのトランザクションをまとめ上げるプロセスが存在しなくなるため、一連の処理の一部が失敗した場合のデータの整合性担保が難しくなる。
      • (What) アーキテクチャとしては、エラー通知のトピックとエラー処理サービスを立ててロールバックを実行する。
      • (How) 通知の具体的なコンポーネントとして、SNS/SQSを使ったDLQを使用する。

Bad Point

上記のように良書ではあるものの、残念 or ここは改善できそうというポイントもありました。

  • CI/CDパイプラインを作らず全てコマンド手動実行

    • package.jsonにパッケージングやデプロイ用のコマンドを書いてまとめてはいるものの、いちいち自分で実行しないといけないのは効率が悪いです。
    • 画像処理のためにffmpegを入れるLambdaのデプロイパッケージのZIPファイルは40MB近くあるため、ネットワークによってはupdate-function-codeが失敗します。これがすごいストレスです。S3にアップロードしてからコマンドを叩けばデプロイ可能ですが、AWS SAMやServerless Frameworkを使ったCI/CDパイプラインを作ればストレスフリーかつ時短になったはず。
    • 折角クラウドサービスを使ってるんだから、手作業でボトルネックができちゃうのは勿体無い点です。
  • 使用するサービスが古い

    • 面白みに欠けるという意味ではなく、すでにdeprecatedになっている機能や代替サービスの使用を前提としていたことがあって何度か心が折れそうでした笑
    • Auth0は認証用のウィジェットとして組み込みのUIではなく、Auth0がホストするUI(Universal UI)の使用が推奨されていました。こっちの方がライブラリ管理が少なくてベターに感じます。
    • Firebase Realtime Databaseの代わりに(beta版ではありますが)Firestoreを利用が最近は多いようです。
    • 認証は委譲トークン(Delegation Token)を使用する前提で記載されていましたが、この手法による認証方法は廃止されていました。
  • 長時間処理するバッチコンピューティングの利用や、既存のサーバーを使ったレガシーアプリケーションとの共存・マイグレーションについて言及がなかった。

    • 実際には一からサーバーレスで作ることは(特にエンタープライズ系のサービスだと)少ない訳ですし、サーバーありのサービスとの共存や割り切り方については何かしら意見が欲しかったところです。
    • 例えばAWS BatchやEMRを使うケース、ECRを併用するケースってどう切り分けているのかしら...??とか。

まとめ

上記のようにGood/Badポイントは双方あるもののが、総じてサーバーレスアーキテクチャと実装を理解し、イメージするには良書でした。 単にAWS Lambdaを使おうに止まらず、サービスを作るために必要なコンポーネントやそれぞれの役割、原則について非常によくまとまっていたので、これからサーバーレスに挑む人には是非おすすめしたい書籍です。

せっかくなので、IBM Cloudや最近認定を取ろうと目論んでいるGCP、もしくはOSSをふんだんに使ったケースでも同じ or さらに発展させられないか試してみようと思います。


以上。

ブラウザからREST APIでAmazon S3にファイルをアップロードするときに気をつけること

書籍『AWSによるサーバーレスアーキテクチャ』(翔泳社)を読み進めているときにS3のファイルアップロード関連でつまづいたところが多々あったので、気をつけるべきところとして手順と一緒にまとめます。

AWSに関わる動的な処理を全てJavaScriptで実装することを選択した場合、AWS Lambda上ではAWS SDK for JavaScript一択ではありますが、ブラウザの場合は生のJavaScriptで記述することも可能です。

今回はブラウザ側で実行されるS3関連のコードをSDKを使わずREST APIで扱った時のメモです。 (書籍に従って生JSでゴリゴリ書きましたけど、潔くSDKを使えばこういったところで躓かなかったのではと思わずにはいられない。)

www.shoeisha.co.jp

やること

  • 署名付きURLを発行する。
  • バケットのアクセス権限を設定する。
  • REST API経由でリクエストを投げる。

署名付きURLを発行する

AWS S3 署名バージョン4でリクエストする

  • ファイル名(オブジェクトのキー)、バケット名、有効期限を使って署名付きのURLを発行します。このとき、署名バージョン4でリクエストします。
    • V4以外は受け付けません。明示的に指定した方がいいかも。
    • ここはLambda + API Gatewayで実装すると扱いやすい。

AWS regions created before January 30, 2014 will continue to support the previous protocol, Signature Version 2. Any new regions after January 30, 2014 will support only Signature Version 4 and therefore all requests to those regions must be made with Signature Version 4

https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/API/sig-v4-authenticating-requests.html

以下、コード例。

"use strict";

const AWS = require("aws-sdk");
const S3 = new AWS.S3({
    signatureVersion: 'v4'
});
const crypto = require("crypto");

function getSignedUrl(fileName) {
    const prefix = crypto.randomBytes(20).toString("hex");
    const params = {
        Bucket: process.env.UPLOAD_BUCKET,
        Key: prefix + "/" + fileName,
        Expires: 600
    };
    return S3.getSignedUrl("putObject", params);
}

module.exports = {
    getSignedUrl
};
  • オペレーション名を一緒に付与すること

    • オペレーションを指定するときは、putObjectとキャメルケースで指定すること。PutObjectと先頭大文字で指定するとエラーで弾かれる。
    • 公式ドキュメントには上記は明記されていないが、Sampleにはちゃっかりキャメルケースで指定されている。
  • ここで返却される署名付きURLは仮想ホスト形式で返されます。

    • http://{bucket-name}.s3.amazonaws.com
    • http://{bucket-name}.s3-aws-region.amazonaws.com

バケットのアクセス権限を設定する

バケットポリシー

まずはパブリックアクセス権限が付いていたら外します。 今回は署名付きURLでダウンロード/アップロードを行うため、リクエストの度にリクエスト者に権限が付与される仕組みにするためです。

バケットを選択 -> アクセス権限 -> バケットポリシーを開いてドキュメントを削除する。バケット一覧で該当のバケットに"非公開"と記載されていればOK。

常に最小限の権限を付与することが推奨されているため、不用意にパブリックアクセスを許可することは回避した方が良いです。

CORS設定

AWSとは別ドメインからアクセスすることになるので、どこから/どんなオペレーションが許可されるかバケットに設定する必要があります。 バケットを選択 -> アクセス権限 -> CORSの設定から以下のように設定を追加します。これだけ。

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>*</AllowedOrigin>
        <AllowedMethod>POST</AllowedMethod>
        <AllowedMethod>PUT</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

あと地味なTipsとしては、1行目の<?xml...の記載は設定のエディタに書かなくても勝手に追加されます。

REST API経由でリクエストを投げる

PUTリクエストで投げる。

オブジェクトの新規作成をするんだからPOSTリクエストじゃね?と直感的に思いつきますが、PUTリクエスで投げます。POSTメソッドでリクエストを投げてもAccess Deniedと403が寂しく返ってくるだけです。 思い返してみれば、オペレーション名はPutObjectだもんね。

おそらく同一キーのオブジェクトに対しては上書きもできることから、POSTメソッドではなくPUTメソッドのリクエストにしているのではと推測します。 --> REST API Reference: PUT Object

Content-Typeはファイルのものを指定する

画像や動画をHTMLから送信する場合の定石だとContent-Type: multipart/form-dataでデータをバックエンドに送信しますが、S3へのアップロードに関しては単一ファイルの場合はmultipartリクエストを行うのは間違いです。 ファイル本体のContent-Typeを指定しましょう。

例えば、MP4の動画をアップロードする場合は、Content-Type: video/mp4といった具合です。

"use strict";

/**
 * ファイルをS3バケットにアップロードする。
 * @param {string} url アップロード先S3バケットの署名付きURL
 */
function upload(url) {
    // MP4の動画を添付したと想定。
    const uploadBtn = document.getElementById("uploadButton");
    const file = uploadButton.files[0];

    // S3バケットにアップロード実行。
    $.ajax({
        url: url,
        type: "PUT",
        data: file,
        processData: false,
        contentType: "video/mp4"
    })
    .done(response => {
        console.log(response);
        alert("Upload Finished!");
    })
    .fail(err => {
        console.log(err);
        alert("Failed to upload...");
    });
}

実はこれもちゃっかり公式ドキュメントに記載されています。日本語版にはないですけどね。 以下のExample2にJPEG画像の例が参考になります。 https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/API/RESTObjectPUT.html?shortFooter=true#RESTObjectPUT-responses-examples


ブラウザに含めるJSファイルのサイズを気にしてSDKを入れられない場合などに参考にしていただければと思います。

以上。