こんにちは、エス・エー・エス株式会社の海田です。
昨年に引き続き、今年の夏も暑いですね。
先日下の娘が通っている幼稚園の近所で夏祭りがありました。その中で「スイカ割り」イベントがあり、子供たちが列を作って並んでいました。
スイカ割りは、目隠しをして、その場でぐるぐる回って感覚を鈍くさせ、ターゲットとなるスイカめがけてよろよろ進みます。そしてここかなと思う場所で渾身の力で棒を振り下ろし、見事スイカを割れればゲームクリアですね。
この時重要になってくるのが、「まえまえ!、もっと右!もうすこし左!」というギャラリーの方々の応援です。 なかなか自分一人では達成が難しいミッションを、仲間の力を借りて遂行 します。お仕事も同じで、全部一人でやろうとすると大変で、たまには得意な仲間にお任せして進めるというのも大切なのかなと思います。これは実はシステム開発においても同様で、開発が大変な機能はそれが得意なサービスに任せるという考え方が大切になってきます。今日はそんなお話です。
1.機能要件と非機能要件 システム構築するにあたって、 機能要件 と 非機能要件 という言葉は聞いたことがあるかもしれません。このうち機能要件とは、例えば「在庫管理機能を有し、必要に応じて在庫商品の増減を可能とする」や「受注処理機能を有し、受注管理を実施することができる」などに該当します。これは、 システムに本当に実装したい機能 であり、お客様にとっても実装したい機能そのものであるので、イメージがしやすく要件として定義やすいです。一方、非機能要件とは、 システムそのものが実装してもしなくても本当はどちらでもいい のですが、システムとして 安全に利用していくためにはなるべく実装したほうがよい 機能に該当します。例えば、システムを利用するユーザを判定する 「認証機能」 、ユーザとシステム間のデータ送受信が安全に行われるための 「通信の暗号化機能」 、システムが障害や災害時にもできるだけ稼働するための 「冗長化機能」 、その他にもメンテナンスがしやすいとか、拡張しやすいとか、地球環境に優しい・・などの機能もこちらに入り、それらの要件を定義していきます。
先ほど、非機能要件はシステムそのものが実装してもしなくても本当はどちらでもよいと言いましたが、例えば認証機能や暗号化機能がないコミュニケーションツールを利用することを想像してみてください。私の許可なく、勝手に「私」として発言され、私のやりとりをいつでも誰でも確認できてしまうツールを利用したい!・・とは思いませんよね。このように セキュリティに絡む非機能要件については、システムへの実装が必須 となっています。というか、実装しないと絶対に利用してもらえません。
2.非機能要件を実装し、管理していく大変さ 非機能要件のうち、セキュリティに関する機能については実質的に実装が必須であることは先ほど書きました。つまり、システムとして非機能要件を組み込む必要があるということです。その組み込み方ですが、 かつては一つのサーバ内に、機能要件と非機能要件を全てまとめて実装 していました。図にすると以下のような形です。
ここで、「 ④アプリ」が本当に実装したい機能要件 であり、それ以外(①-③)は全て非機能要件となります。非機能要件はもちろんこれ以外にもあるかもしれませんが、ここでは省略しています。このように機能・非機能要件を全て一つのサーバ内で実装していくのは大変です。上の絵では、サーバが大変・・という見え方になっていますが、 ここで本当に大変なのは、このシステムを構築するメンバーが大変 ということです。開発メンバーは本当に実装したいのは④なのに、①-③についても考慮し、④と一緒に作り上げていかなくてはならないからです。
3.非機能要件をお任せできるAWSサービス 下の図を見てください。先ほどの図の①-④の機能をうまく役割分担しています。
ここでは様々なAWSサービスが出てきますが、まず最初に何をお伝えしたいかと言うと、①-③の非機能要件を上記表示の各AWSサービス(「Cognito」「ACM」「Route53」)に 完全にお任せできる ということです。 開発者は「④アプリ」を実装するためだけに力を注げる ということですね。
そして、特にここに表示されている「Cognito」「ACM」「Route53」とのやりとりに関しては、中央の 「Application Load Balancer」が一括して担当 します。これは「④アプリ」を実装するEC2に余計な手間をかけさせないということであり、 EC2に届く前には、全ての非機能要件の処理が終わっていることを示しています。 また「Application Load Balancer」はAWSのロードバランスサービスであり、これは マネージドサービス(運用維持管理をAWSにお任せできるサービス) なので、運用維持管理者の負荷もぐっと減ります。
冒頭の「スイカ割り」でも書いたように、なかなか自分一人では達成が難しいミッションを、仲間の力を借りて遂行します。 開発が大変な機能はそれが得意なサービスに任せるという考え方 を用いてシステムアーテクトしていくのがいいのかなと思います。
それでは具体的に見ていきます。
①認証システム(Amazon Cognito) アプリケーションを利用することができるユーザを選別する、いわゆる ログイン機能 を実装できます。認証機能を アプリケーションから切り離し、Cognitoに任せることができます 。またCognitoは 「HostedUI」 というシンプルなログイン画面を提供してくれますので、特にこだわりがなければこれを利用することで簡単にログインシステムを作成できます。さらに、Cognitoは外部のID(OpenID)を利用してのログインも可能とします。例えば Googleアカウントを持っている人はその情報を用いてこのアプリにログインできます。 私もこれらの機能を利用して作成してみました。
左側の 「Continue with Google」 左側の「Continue with Google」がGoogleでのログイン、右側は一般的なログインです。右側の場合は、Cognitoでユーザを登録・管理していきます。ライオンの画像を入れてみました。このように画像や背景はCSS編集や画像アップロード機能がデフォルトで備わっているのでそれらを利用して編集できます。私はCSSは全く無知なので検索で探してコピペしただけなのですが、これくらいの色の改修であれば編集できるようです。
②通信の暗号化(AWS Certificate Manager) 画面上部のPCアイコン(ユーザ)から「Application Load Balancer」へアクセスするときの通信を暗号化 (HTTPS化) させるための仕組みを提供します。HTTPS化させるためには、事前に独自ドメインが必要です。お名前.comなどでドメインを取得し、そのドメインの所有者であることを検証すれば、ACMで証明書を無料で発行できます。その証明書をALBにアタッチすることで、通信を暗号化させることができます。
画面上部のユーザは、ALBめがけて独自ドメイン(例えば、www.kaida.com)でアクセスします。この時、ユーザのPCブラウザと、ALB間で暗号化通信が行われます。暗号化されたデータはALBで復号化されます。つまり、 ユーザPCブラウザ→ALBは暗号化(HTTPS)通信 ですが、 ALB→EC2間は非暗号化(HTTPSではなくHTTP)通信 です。これは問題ないのかという疑問も昔湧いたことがありましたが、そもそもALB⇔EC2はAWSCloudデータセンター内である(ここが盗聴されるのはそもそも大問題!)のと、復号化処理をALBにお任せするということでEC2側の負荷を減らせるメリットもあります。
③名前解決(Route53) 取得したドメインとAWSサービス内のDNS名を関連付ける機能として利用します。ここでは、外部で取得したドメインと、ALBのデフォルトのDNS名を関連付けるために利用します。ALBを構築した時点でデフォルトのDNS名で利用することはできるのですが、その場合ACMの証明書を発行できない(ACMはamazon.comドメインのSSL証明書を発行できない)のでACMを利用したHTTPS化することができません。そのため独自ドメインを取得し、そのドメインとデフォルトのDNS名を関連付ける必要があります。その関連付けをRoute53で行います。
4.まとめ そして、先ほど挙げた「①認証システム(Amazon Cognito)」、「②通信の暗号化(AWS Certificate Manager)」、「③名前解決(Route53)」はすべて「Application Load Balancer(ALB)」と連携します。最終的にGoogleアカウントでログインできるためには、①-③が全て必要ですが、各サービスの処理結果は全てALBが連携してくれます。ALBは本来のロードバランサーとしての機能も持っているので、配下のEC2を複数台用意して負荷分散することももちろん可能です。
今回は概要ということで細かい設定等までは記載しませんでした。実際に非機能である①-③を各AWSサービスにお任せして、ドメイン、暗号化、そして認証を経たユーザだけがアクセスできるようなシステム(と言っても簡単なWEBサイトですが)を作成しましたので、その内容については次回記載できればと思います!
読んで下さってありがとうございました!
本記事を記載するにあたり参考にさせていただいたサイトとなります。